完全背包(从二维到一维)

完全背包(从二维到一维)_第1张图片

 完全背包(从二维到一维)_第2张图片

 图片来源活动 - AcWing

有 N件物品和一个容量为 V 的背包,每件物品有各自的价值且能被选择无数次,要求在有限的背包容量下,装入的物品总价值最大。

一,暴力解法(容易超时)

#include
using namespace std;
const int N=1e3+10;
int v[N],w[N],f[N][N];

int main(){
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>v[i]>>w[i];
	}
	
	for(int i=1;i<=n;i++){
		for(int j=0;j<=m;j++){
			for(int k=0;k*v[i]<=j;k++){
				f[i][j]=max(f[i-1][j-k*v[i]]+w[i]*k,f[i][j]);
			}
		}
	}
	cout<

二,二维版本

#include
using namespace std;
const int N=1e3+10;
int a[N],b[N],dp[N][N];
 
int main(){
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++)cin>>a[i]>>b[i];
	
	
	for(int i=1;i<=n;i++){
		for(int j=0;j<=m;j++){
			dp[i][j]=dp[i-1][j];
			if(j>=a[i])
			dp[i][j]=max(dp[i][j],dp[i][j-a[i]]+b[i]);//与01背包相似不同点是01背包在第i-1层找最大值 
		}                                             //而完全背包在第i层寻找最大值(因为完全背包每层可以选择多个) 
	}
	cout<

三,一维版本(与01背包相似只是j的遍历方向不同)

#include
using namespace std;
const int N=1e3+10;
int a[N],b[N],dp[N];

int main(){
	int n,m;
	cin>>n>>m;
	for(int i=1;i<=n;i++)cin>>a[i]>>b[i];
	
	
	for(int i=1;i<=n;i++){
		for(int j=a[i];j<=m;j++){
			dp[j]=max(dp[j],dp[j-a[i]]+b[i]);  //背包容量是从大到小的因此j一定大于a[i] 
		}
	}
	cout<

你可能感兴趣的:(算法)