【程式碼隨想錄】完全揹包

SaTsuki26681534發表於2024-03-21

題目描述

image

分析

所謂完全揹包就是各種物品的數量為無限的情況,這種題其實想一下是比01揹包簡單的,因為沒有了物品數量的限制,往揹包裡放物品的過程變得更簡單直觀了。
很容易得到,在完全揹包裡只能遍歷揹包容量,而不能遍歷物品,因為這時物品是無限的,這樣的話我們只需要一邊迴圈,從dp[0]一直遍歷到dp[V]即可,而且這直接就是往揹包裡一個個放物品的過程。
由於只有一遍迴圈,所以不必擔心dp陣列被覆蓋的問題,而且由於只進行一邊迴圈,所以只能正序遍歷dp陣列而不能倒序。
複習一下為什麼01揹包裡必須倒序遍歷揹包空間:
image
其實在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;
}

相關文章