背包九讲第一讲-简单的0/1背包问题有感1.3

如何改进呢?

我觉得大家还是可以先看看这一幅图


ok。。。。。。我们先focus on输出14,那部分正确的。
0 0 5 5 5 5 5
0 0 5 8 8 13 13
0 0 5 8 9 13 14
不知道大家对于这个有没有什么想法。。。。。。
是不是觉得,好像有一些东西是重复的,没用的。
我那时候看上去我觉得,可能能够通过使用dp一维数组来降低我们的复杂度。
事实上看资料发现,的确如此,但是我犯了一个错误。

思路

我们可以直接用一个dp[j]数组,注意!这里的dp[j]数组就是说,当现在空间限制为j时候的最大价值和!
状态转移方程:
if(j-w[i]>=0)
bag[j]=max(bag[j],bag[j-w[i]]+v[i]);
初值:
一开始我把dp数组从j=0~zone都赋值了0;因为现在没有一件物品,对应了每个空间限制的最大价值和都是0!
然后我们从第一件物品开始,一件一件的考虑

这个时候我稍稍将代码改动,即可得出:

#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;	
long long bag[10001];
int main()
{
	int n=0;
	int zone=0;
	int v[101];
	int w[101];

	while(cin>>n)
	{
		cin>>zone;
		for(int i=1;i<=n;i++)
		{
			cin>>w[i]>>v[i];
		}
		for(int i=0;i<=zone;i++)
		bag[i]=0;
		for(int i=1;i<=n;i++)
		{
			for(int j=0;j<=zone;j++)
			{
				if(j-w[i]>=0)
				bag[j]=max(bag[j],bag[j-w[i]]+v[i]);
			}
		for(int i=0;i<=zone;i++)
		cout<<bag[i]<<" ";
		cout<<endl;
		}
	}
}

但是因为我的考虑不周,出现了错误。

大家发现了吗,bug在于,同一件物品在足够大的背包空间限制下,可以自己不断叠加!!
我曾经尝试进行下面的补救:
如果能够进行第一次优化,那后面的就直接赋值,不再进行状态转移。
但是这引起了另外一个问题。。。。。。无法照顾到背包容量足够大到可以容纳几件物品。
所以。。。。我找资料寻求帮助。。。。。
大家也可以想一想,整体思路是没有错的,但是我们应该如何修改呢?








没错!j从zone开始递减!就可以避免了自己的在足够大背包空间的限制下进行叠加!!!

怎么样?是不是很巧妙!!对应的dp[zone]就是我们在所要求的背包容积下的最大价值和!!

代码展示

#include<iostream>
#include<cmath>
#include<algorithm>
using namespace std;	
long long bag[10001];
int main()
{
	int n=0;
	int zone=0;
	int v[101];
	int w[101];

	while(cin>>n)
	{
		cin>>zone;
		for(int i=1;i<=n;i++)
		{
			cin>>w[i]>>v[i];
		}
		for(int i=0;i<=zone;i++)
		bag[i]=0;
		for(int i=1;i<=n;i++)
		{
			for(int j=zone;j>=0;j--)
			{
				if(j-w[i]>=0)
				bag[j]=max(bag[j],bag[j-w[i]]+v[i]);
			}
		for(int i=0;i<=zone;i++)
		cout<<bag[i]<<" ";
		cout<<endl;
		}
	}
}

---还有什么要注意的呢???
未完待续。。。。。。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值