乙個旅行者有乙個最多能用m公斤的揹包,現在有n件物品,它們的重量分別是w1,w2,...,wn,它們的價值分別為c1,c2,...,cn.若每種物品只有一件求旅行者能獲得最大總價值。
輸入的第一行為t,表示測試資料的組數。對於每組測試資料的第一行:兩個整數,m(揹包容量,m<=200)和n(物品數量,n<=30),第2..n+1行:每行二個整數wi,ci,表示每個物品的重量和價值。
對於每組測試資料輸出僅一行,乙個數,表示最大總價值。
110 4
2 13 3
4 57 9
12#include【**】
#include
using namespace std;
int w[20],v[20],f[20];
int main()
}printf("%d",f[m]);
return 0;
}
//判斷和不判斷的差別
/*12
1 1 1 1 1 1 1 1 1 0
4 4 4 4 4 4 3 3 1 0
9 9 8 8 6 5 5 3 1 0
12 10 9 9 6 5 5 3 1 0
*//*
141 1 1 1 1 1 1 1 1 1
4 4 4 4 4 4 4 3 3 3
9 9 9 8 8 8 5 5 5 5
14 14 14 9 9 9 9 9 9 9
*/
//每一件物品的狀態抉擇為放還是不放 如果不放 前i件物品 不超過v的最大值就是前i-1件物品不超過v的最大值
否則 放就是 前i-1物品放入 v-w[i]的最大值加上要放入的當前的價值
優化 二維陣列優化為一維陣列 f[v]為重量不超過v的最大值
【**】
#include#includeusing
namespace
std;
int w[20],c[20],f[20][20
];int
main()
}printf("%d
",f[n][m]);
return0;
}
完全揹包
【**】
二維
#include#includeusing
namespace
std;
int w[20],f[20][20],c[30
];int
main()
}printf("%d
",f[n][m]);
return0;
}
一維
#include#includeusing
namespace
std;
int f[20],w[20],c[20
];int
main()
}printf("%d
",f[m]);
return0;
}
資料 其實沒多大用這資料。。。。
12(二維)011111
1111
0133
4444
4401
3556
8899
0135
5699
1012
12(一維)01
3556
9101012
01揹包和完全揹包的區別是完全揹包每種物品有無數件 所以每次決策就改變了 不在是取或不取 而是取幾件、
分析一下** 發現兩個**很像 區別就是01揹包體積迴圈是 v--1,而完全揹包是1--v
why?
為什麼01逆序 完全順序
先講01如果順序後會怎樣呢?
我們知道f[v]=max(f[v],f[v-w[i]]+c[i]);如果順序1--v,因為f[v]是由f[v-w[i]]推過來的,如果順序的話 f[v-w[i]]一定推完了 我們可能在f[v-w[i]]時就已經
放入了i物品 ,所以你推的f[v]就拿了兩件i物品了,所以01要逆推,,,反之,,拿好幾件就是完全 順推了。。。。
我也剛懂。。。糊里糊塗的。。。自己好好想想吧qaq
揹包問題(0 1揹包 完全揹包)
0 1揹包 有n件物品和乙個容量為v的揹包。第i件物品的費用是c i 價值是w i 求解將哪些物品裝入揹包可使價值總和最大。重要的點在於 每種物品僅有一件,可以選擇放 不放子問題 f i v 表示前i件物品恰好放入乙個 容量為v 的揹包可以獲得的最大價值。狀態轉移方程 遞推式 f i v max 考...
0 1揹包和完全揹包問題
有乙個容量為 n 的揹包,要用這個揹包裝下物品的價值最大,這些物品有兩個屬性 體積 w 和價值 v。定義乙個二維陣列 dp 儲存最大價值,其中 dp i j 表示前 i 件物品體積不超過 j 的情況下能達到的最大價值,每件物品只能被新增一次。設第 i 件物品體積為 w,價值為 v,根據第 i 件物品...
01揹包和完全揹包問題
搞了好久終於來寫dp了 完全揹包問題和01揹包問題只有乙個區別,就是完全揹包中物品可以取無數次但01揹包只能取一次。而因此帶來的解法也只有乙個不同,那就是用滾動陣列時01揹包要從後向前列舉而完全揹包只需要從前往後列舉即可,具體為什麼這個問題屬實困惑了我一陣子。完全揹包從前向後列舉時前面的狀態可能已包...