关于0-1背包问题

有n种物品,每种只有一个,第一种物品的体积为Vi,重量为Wi。选一些物品装到一个容量为C的背包,使得背包内物品在总体积不超过C的前提下重量尽量大。

//剩余体积作为状态 

	for(int i=n;i>=1;i--)
	for(int j=0;j<=C;j++){
	d[i][j]==(i==n?0:d[i+1][j]);
	if(j>=V[i]) d[i][j]=max(d[i][j],d[i+1][j-V[i]]+W[i]);
}


//把前i个物品装到容量为j的背包中的最大总重量

	for(int i=1;i<=n;i++) 
	for(int j=0;j<=C;j++){
	f[i][j]=(i==1>0:f[i-1][j])
	if(j>=V[i]) f[i][j]=max(f[i][j],f[i-1][j-V[i]+W[i]]);
}

//不必把V和W保存下来,节省了一些空间

	for(int i=1;i<=n;i++) 
	scanf("%d %d",&V,&W);
	for(int j=0;j<=C;j++){
	f[i][j]=(i==1?0:f[i-1][j]);
	if(j>=V) f[i][j]=max(f[i][j],f[i-1][j-V]+W);
}

//使用滚动数组 优点:减少内存开销 缺点:只记录最后一个阶段的状态 ,无法打印字典序 
滚动数组中f[i]保存的是f(i-1,j)的值。
	memset(f,0,sizeof(f));
	for(int i=1;i<=n;i++){
	scanf("%d %d",&V,&W)
	for(int j=C;j>=0;j--)
	if(j>=V) f[j]=max(f[j],f[j-V]+W);
}

如果想打印字典序,即使用二维数组逆向推,也都不一定能保证字典序最小(字典序比较是从前往后)

发布了57 篇原创文章 · 获赞 58 · 访问量 665

猜你喜欢

转载自blog.csdn.net/weixin_43568895/article/details/103361181