動態規劃 POJ 1837 Balance

2021-09-21 07:10:51 字數 1801 閱讀 2070

這段時間要沉迷刷題一段時間了,就讓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 ...