HDU 3127 WHUgirls(二維揹包)

2021-07-10 02:46:55 字數 1829 閱讀 4178

有一塊x*y的布,可以裁剪成n種不同的小碎步布,剪成xi*yi的碎布可以獲得wi元,問將這塊布剪成小碎布最多能獲得多少錢?只能橫著剪或者豎著剪,不能從中間摳出一塊

二維dp,dp[j][k]表示j*k的布剪成小碎布最多能得到多少錢,j*k可以由三個小長方形組成:(這裡有切割方式)

1、xi*yi、 j*(k-xi)、 (j-xi)*yi

2、xi*yi、 xi*(k-yi)、 (j-xi)*k

3、xi*yi、 j*(k-xi)、 (j-yi)*xi

4、xi*yi、 yi*(k-xi)、 (j-yi)*k

所以轉移方程式是:

dp[j][k]  = max(dp[j][k], max(dp[j-xi][k]+dp[xi][k-yi], dp[j][k-yi]+dp[j-xi][yi])+wi);

dp[j][k]  = max(dp[j][k], max(dp[j-yi][k]+dp[yi][k-xi], dp[j][k-xi]+dp[j-yi][xi])+wi);

重點來了!

網上的絕大多數部落格式直接用以下**得到的dp[x][y]作為最終的值輸出,我覺得這並不是最終的正確答案,下面的**過不了hdu -discuss裡面的乙個資料: 1

4 8 26

1 5 1

3 7 10

3 19 500

5 10 1000

這個答案應該是2521

布剪成小碎布之後還剩下一些沒有價值的布,這有時會造成dp[x][y]偏小(我覺得這也是為什麼三個for位置換了之後,直接輸出dp[x][y]會wa的原因),

需要再加上**中的兩句話

下面這兩個**都是ac的

#include #include #include #include #include using namespace std;

int dp[1010][1010];

int main()

if(j>=yi && k>=xi)}}

} int ans = dp[x][y];//以下兩句是我認為要加上去的

for(int i=0; i<=x; i++) ans = max(ans, dp[i][y]+dp[x-i][y]);

for(int i=0; i<=y; i++) ans = max(ans, dp[x][i]+dp[x][y-i]);

printf("%d\n", ans);

} return 0;

}

#include #include #include #include #include using namespace std;

int dp[1010][1010];

int x[15], y[15], w[15];

int main()

if(j>=y[i] && k>=x[i])}}

} int ans = dp[x][y];

for(int i=0; i<=x; i++) ans = max(ans, dp[i][y]+dp[x-i][y]);

for(int i=0; i<=y; i++) ans = max(ans, dp[x][i]+dp[x][y-i]);

printf("%d\n", ans);

} return 0;

}

HDU 3127 WHUgirls 二維完全揹包

題意 給出乙個長為a,寬為b的布,再給出n個圍巾的規格 長x,寬y,價值c 問怎樣裁剪能夠得到最大的價值。第一次做的時候不會 然後放到今天做 發現還是不會 於是又 看題解了 因為相同規格的圍巾可以重複剪多次,且圍巾的長和寬相當於兩個約束,所以可以轉換為二維費用的完全揹包問題。然後就是圍巾的裁剪 第一...

hdu 3496 二維0 1揹包

很典型的一道二維揹包的題目,在保證時間不超出l的情況下還要保證碟片恰好為m。第一次做二維揹包,錯了n多次,原來才發現陣列中應該為i,不應該為j。include include include include include using namespace std const int inf 1000...

hdu 2159 FATE (二維揹包)

解題報告 二維揹包的問題,如果沒有看過的話,建議去看看揹包9講中的第五個問題。本題中有每殺乙個怪,會獲得一定的經驗,同時減少一定的忍耐度,我用二維陣列dp來存放每次獲得的經驗值,b i 為每次消耗的忍耐 所以可以的到遞推關係式 dp i j max dp i b i j 1 dp i j 資料有點多...