這段時間要沉迷刷題一段時間了,就讓csdn陪我一起吧!題目的大致意思是說,有乙個天平,題目給出天平上具有的鉤子數量為c,擁有的物品數量為g,現在要求你要利用這些重物,讓天平平衡,當然要求是要把全部的重物都掛到鉤子上,允許有鉤子空著。
結果是要求輸出可以是天平達到平衡的懸掛方法種數。
這種問題一看就是動態規劃的問題,因為讓你求達到平衡的懸掛方法種數,而且要求用時1000ms,可以想一下,如果不是動態規劃的話,你需要嘗試每一種方法,然後計數,這樣你嘗試方法的時間就都浪費了,肯定會超時!(當然,這只是我粗淺的理解,大牛勿噴)
定義平衡度
然後說這道題,對於天平問題,因為是讓他們平衡,我們就可以考慮定義乙個右邊減左邊的量為其平衡度,也就是當右邊質量減左邊質量為0的時候,即天平平衡。
但在計算機中,尤其是想在dp陣列中表示平衡度,就只能用乙個非負整數來衡量,可以看到題目給的輸入範圍,2≤g≤20,1≤重物質量≤25,天平的左右臂長為15,這樣的話,最不平衡的情況就是20個重量為25的重物全部被放在最左邊或最右邊,這樣的話平衡度為-7500或7500,但前面說了,對於陣列,他們只能是非負的,所以這裡全體增加乙個偏移量,將-7500~7500的平衡度移動到0 ~ 15000,保證可以dp。
遞推公式
平衡度定義完成,下面就是dp最關鍵的遞推公式。首先定義dp[i][j]為用前i個重物掛到鉤子上使天平平衡度為j時的掛法種類數。這樣的話,最終要求解的結果就可以用dp[g][7500]來表示。
進而我們可以得到遞推公式:
dp[i][j] = d[i-1][j-c[k]*g[i]]
下面我具體解釋一下這個遞推公式,不明白的同學可以跟著思考一下。
dp[i][j]表示我用前i個重物去掛到鉤子上,使天平平衡度為j的掛法種數。那麼這個種數等於什麼呢?我們考慮第i個重物,我們在考慮怎麼掛第i個重物的時候,前i-1個重物肯定已經掛好了,那麼我們就可以選擇將這個重物掛在不同的鉤子上,比如我們有處於c[1]位置的鉤子和c[2]位置的鉤子。假設我們將第i個重物掛在c[1]位置的鉤子上,那麼這樣的種類數是不是就等於dp[i-1][j-c[1]*g[i]],也就是我們掛完第i-1個重物的時候,如果它的平衡度為j-c[1]*g[i],那麼我們將第i個重物掛在c[1]上的時候,它的平衡度就是j。這個如果理解後,那麼c[2]位置也是一樣的,又由於他們都是到達同一狀態,所以需要將他們加起來,就得到了dp[i][j]。
下面給出ac**:
#include
#define maxc 25
#define maxg 25
using
namespace std;
int dp[maxg]
[15010];
int c[maxc]
;int g[maxg]
;int c, g;
void
init()
g[i]=0
;}for(
int i =
0; i < maxc; i++)}
intmain()
for(
int i =
1; i <= g; i++
)for
(int i =
0; i <=
15010
; i++
) dp[0]
[7500]=
1;for(
int i =
1; i <= g; i++)}
}}printf
("%d\n"
, dp[g]
[7500])
;return0;
}
演算法 動態規劃poj1837
複習了動態規劃 0 1揹包問題,核心方程就是 if c i j f i j f i 1 j 如果揹包的容量,放不下c i 則不選c i else f i j max f i 1 j f i 1 j c i v i 這裡註明一點,i指代物品數量,j指代揹包容積,那麼有兩種情況,乙個是不要第i件物品,那...
poj 1837 Balance 動態規劃
使用迭代器對stl容器進行遍歷的方法 for set iterator it check.begin it check.end it it 本題 a存掛鉤位置 b存物品質量 把掛在天平左邊的物品的質量視為負數 反之為正數 總質量的極限為20件重25的物品都掛在15的天平掛鉤處 即7500 dp i ...
poj 動態規劃 1141
dp練習的第三道題,依然花了我斷斷續續好幾個小時 有人說看到題目裡的 2.if s is a regular sequence,then s and s are both regular sequences.3.if a and b are regular sequences,then ab is ...