动态规划学习之0-1背包和完全背包

背包问题大体上有三种类型,分别是0-1背包,完全背包和介于其中的背包问题。其中又有很多小的细节改变,比如说背包是否要求刚好装满。一般求解的是背包不要求刚好装满,只要求在限制范围内的最大价值就可以。

0-1背包的思路是这样的,不断地向背包添加物品,对于一个物品,当背包容量为v时,选择是添加当前物品进背包还是不添加直
接用前面的安排。V[j][C] = max{V[j-1][C],V[j-1][C-w[j]]+value[j] },表示选择不添加当前这个背包还是添加这个背包,对应的例子:

Noweightvalue
123
234
345
那么0-1背包的对应状态表应该为 C=5时:

 12345
103333
203447
303447
一种最优化的时间,空间地方式是将存储状态改成一维数组,这个数组每次从C=max开始添加背包,这样C-W[i]就是上一个状态的值,可以保证每个背包只被添加一次。

对于完全背包C=1开始,这样C-W[I]就是可以被添加多次的此次被计算过的最大值。

完全背包上面的例子的状态应该是:

 12345
103366
203467
303467
0-1背包时候最优空间的解法方程是

for(int i=0;i<n;i++)
   for(int j= V;j>=0;j--)
   {
       if(j>=weight[i])
       {
   if(f[j-weight[i]]+value[i]>f[j])
        f[j] = f[j-weight[i]]+value[i]; 
    }
   }

完全背包的时候最优空间的解法方程是:

for(int i=0;i<n;i++)
   for(int j= 0;j<=V;j++)
   {
       if(j>=weight[i])
       {
   if(f[j-weight[i]]+value[i]>f[j])
        f[j] = f[j-weight[i]]+value[i]; 
    }
   }

0-1背包 code :
#include<iostream>
#include<string.h>
using namespace std;

int main()
{
	int n,V;
	cin>>n>>V;
	int value[n],weight[n];
	for(int i=0;i<n;i++)
	    cin>>value[i]>>weight[i];
	int f[V+1]; //此时不要求刚好装满背包,所以可以将f[V]初始化为0,f[V]存放的是当V为背包容量时,最大地放入价值 
	memset(f,0,(V+1)*sizeof(int));
	for(int i=0;i<n;i++)
	    for(int j= V;j>=0;j--)
	    {
	    	    if(j>=weight[i])
	    	    {
				    if(f[j-weight[i]]+value[i]>f[j])
				         f[j] = f[j-weight[i]]+value[i]; 
				}
				cout<<"i="<<i<<" j="<<j<<":"<<f[j]<<endl;
	    }
	cout<<f[V]<<endl;
	return 0; 
}

完全背包code:
#include<iostream>
#include<string.h>
using namespace std;

int main()
{
	int n,V;
	cin>>n>>V;
	int value[n],weight[n];
	for(int i=0;i<n;i++)
	    cin>>value[i]>>weight[i];
	int f[V+1]; //此时不要求刚好装满背包,所以可以将f[V]初始化为0,f[V]存放的是当V为背包容量时,最大地放入价值 
	memset(f,0,(V+1)*sizeof(int));
	for(int i=0;i<n;i++)
	    for(int j= 0;j<=V;j++)
	    {
	    	    if(j>=weight[i])
	    	    {
				    if(f[j-weight[i]]+value[i]>f[j])
				         f[j] = f[j-weight[i]]+value[i]; 
		    }
				cout<<"i="<<i<<" j="<<j<<":"<<f[j]<<endl;
	    }
	cout<<f[V]<<endl;
	return 0; 
}

学习链接:http://wenku.baidu.com/view/82d6c300de80d4d8d15a4f8d.html#

                    http://wenku.baidu.com/link?url=19k7mBFMIMvDhkqqwwnZvoPLMLtVB88SG7Fd1tINVxSc1BeY46sVj02D64IO8a-mqfcN4_tI9Q4OP_7xIVQz64q5tvntiMuk6yWSiUzIp8q


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值