題目描述
分析
所謂完全揹包就是各種物品的數量為無限的情況,這種題其實想一下是比01揹包簡單的,因為沒有了物品數量的限制,往揹包裡放物品的過程變得更簡單直觀了。
很容易得到,在完全揹包裡只能遍歷揹包容量,而不能遍歷物品,因為這時物品是無限的,這樣的話我們只需要一邊迴圈,從dp[0]一直遍歷到dp[V]即可,而且這直接就是往揹包裡一個個放物品的過程。
由於只有一遍迴圈,所以不必擔心dp陣列被覆蓋的問題,而且由於只進行一邊迴圈,所以只能正序遍歷dp陣列而不能倒序。
複習一下為什麼01揹包裡必須倒序遍歷揹包空間:
其實在01揹包里正序遍歷應該也不是不行,只不過需要加上visited陣列來避免重複放入一個物品的問題,而在完全揹包裡自然沒有這個問題,物品的數量是無限的。
程式碼如下:
#include<bits/stdc++.h>
using namespace std;
//動態規劃:完全揹包
int main(){
int N,V;
cin>>N>>V;
vector<int> weight;
vector<int> value;
int a,b;
for(int i = 0; i < N; i++){
cin>>a>>b;
weight.push_back(a);
value.push_back(b);
}
vector<int> dp(V+1, 0);
for(int j = 0; j <= V; j++){
for(int i = 0; i < N; i++){
if(j - weight[i] < 0){
continue;
}
dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
}
}
for(int i = 0; i <= V; i++){
cout<<dp[i]<<" ";
}
cout<<endl;
cout<<dp[V];
return 0;
}