另一種實現方法:
//動態規劃dp[i][j] 記錄 用j總容量去背起前i個揹包中的若干個揹包 的最大價值
//將用j總容量背起前i個揹包中若干個揹包的問題變為:背第i個揹包+用剩餘容量j-w[i]去背起前i-1個揹包中的若干個揹包.
//即dp[i][j]=v[i]+dp[i-1][j-w[i]];另外還有一種考慮不背第i個揹包的即為:dp[i][j]=dp[i-1][j];
//到此2種情況要判斷取最大,故得出狀態轉移方程:dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+v[i]);
//可見求前i個揹包用j容量的最大價值需要先知道dp[i-1][j]和dp[i-1][j-w[i]]這2個值已經在計算i的前算出.
#include
#include
#include
#include
#include
using namespace std;
int n,c;
int w[20],v[20];
int m[20][20];
int dp[20][20];
int x[20];
void traceback()
x[1]=dp[1][c]>0?1:0;
}int main()
printf("%d\n",dp[n][c]);
traceback();
for(int i=1;i<=n;i++)
printf("%d ",x[i]);
cout
3 54 7
3 52 3
*/
空間上優化後:
(這個貌似不能算出將哪個包放進了)
#include
#include
#include
#include
#include
using
namespace
std;
int n,c;
int w[20],v[20];
int m[20][20];
int dp[20];
int main()
printf("%d\n",dp[c]);
cout
/*3 5
4 73 5
2 3*/
// 01 揹包
#include
#include
using
namespace
std;
int dp[21][1010];
int w[21],c[21];
int main()
for(int i=1;i<=n;i++)else}}
cout
/*5 10
2 13 5
2 53 4
4 3*/
空間優化正如我們上面所說,f[v-c[i]]就相當於原來f[i-1][v-c[i]]的狀態。如果將v的迴圈順序由逆序改為順序的話,就不是01揹包了,就變成完全揹包了,這個後面說。這裡舉乙個例子理解為何順序就不是01揹包了
假設有物體z容量2,價值vz很大,揹包容量為5,如果v的迴圈順序不是逆序,那麼外層迴圈跑到物體z時,內迴圈在v=2時,物體z被放入揹包,當v=4時,尋求最大價值,物體z放入揹包,f[4]=max,這裡毫無疑問後者最大,那麼此時f[2]+vz中的f[2]已經裝入了一次物體z,這樣一來該物體被裝入揹包兩次了就,不符合要求,如果逆序迴圈v,這一問題便解決了。
// 01 揹包
#include
#include
using
namespace
std;
int dp[1005];
int w[105],c[105];
int main()
for(int i=1;i<=n;i++)
}cout
/*5 10
2 13 5
2 53 4
4 3*/
揹包問題 01揹包問題
n個物品,總體積是v,每個物品的體積的vi,每個物品的最大價值是wi,在不超過v的體積下求最大價值 eg揹包容積為 5 物品數量為 4 物品的體積分別為 物品的價值分別為 思路定義乙個二位陣列int f new int n 1 v 1 f i j 就表示在1 i個物品中選取體積小於v的情況的最大價值...
揹包問題 01揹包
有n件物品和乙個容量為v的揹包。第i件物品的重量是c i 價值是w i 求解將哪些物品裝入揹包可使價值總和最大。01揹包中的 01 就是一種物品只有1件,你可以選擇放進去揹包即1,也可以選擇不放入揹包中即0。include include using namespace std const int ...
揹包問題(01揹包)
1085 揹包問題 在n件物品取出若干件放在容量為w的揹包裡,每件物品的體積為w1,w2 wn wi為整數 與之相對應的價值為p1,p2 pn pi為整數 求揹包能夠容納的最大價值。input 第1行,2個整數,n和w中間用空格隔開。n為物品的數量,w為揹包的容量。1 n 100,1 w 10000...