0-1背包恰好背满
2014-02-19 10:58
295 查看
包括此篇文章在内的关于01背包和完全背包问题的文章均转自:http://www.ahathinking.com/
在01背包中,有时问到“恰好装满背包”时的最大价值,与不要求装满背包的区别就是在初始化的时候,其实对于没有要求必须装满背包的情况下,初始化最大价值都为0,是不存在非法状态的,所有的都是合法状态,因为可以什么都不装,这个解就是0,但是如果要求恰好装满,则必须区别初始化,除了f[0]=0,其他的f[1…v]均设为-∞或者一个比较大的负数来表示该状态是非法的。
这样的初始化能够保证,如果子问题的状态是合法的(恰好装满),那么才能得到合法的状态;如果子问题状态是非法的,则当前问题的状态依然非法,即不存在恰好装满的情况。
代码如下:
#include
using namespace std;
int maxV[201];
int weight[11];
int value[11];
int V, N;
void main()
{
int i, j;
scanf("%d %d",&V,
&N);
for(i = 0; i < N;
++i)
{
scanf("%d
%d",&weight[i],&value[i]);
}
for(i = 1; i <= V;
++i)
{
maxV[i] = -100;
}
for(i = 0; i < N;
++i)
{
for(j = V; j >= weight[i]; --j)
{
int tmp =
maxV[j-weight[i]]+value[i];
maxV[j] =
(maxV[j] > tmp) ? maxV[j] : tmp;
}
}
}
为了加深理解,输出每轮循环的状态矩阵如下,对照每个物体的情况,就会理解为什么做那样的初始化了。
在01背包中,有时问到“恰好装满背包”时的最大价值,与不要求装满背包的区别就是在初始化的时候,其实对于没有要求必须装满背包的情况下,初始化最大价值都为0,是不存在非法状态的,所有的都是合法状态,因为可以什么都不装,这个解就是0,但是如果要求恰好装满,则必须区别初始化,除了f[0]=0,其他的f[1…v]均设为-∞或者一个比较大的负数来表示该状态是非法的。
这样的初始化能够保证,如果子问题的状态是合法的(恰好装满),那么才能得到合法的状态;如果子问题状态是非法的,则当前问题的状态依然非法,即不存在恰好装满的情况。
代码如下:
#include
using namespace std;
int maxV[201];
int weight[11];
int value[11];
int V, N;
void main()
{
int i, j;
scanf("%d %d",&V,
&N);
for(i = 0; i < N;
++i)
{
scanf("%d
%d",&weight[i],&value[i]);
}
for(i = 1; i <= V;
++i)
{
maxV[i] = -100;
}
for(i = 0; i < N;
++i)
{
for(j = V; j >= weight[i]; --j)
{
int tmp =
maxV[j-weight[i]]+value[i];
maxV[j] =
(maxV[j] > tmp) ? maxV[j] : tmp;
}
}
}
为了加深理解,输出每轮循环的状态矩阵如下,对照每个物体的情况,就会理解为什么做那样的初始化了。
![](http://simg.sinajs.cn/blog7style/images/common/sg_trans.gif)
相关文章推荐
- 0-1背包使用一维数组
- 0-1背包使用滚动数组压缩空间
- 01背包问题-基本实现
- 完全背包使用一维数组
- 完全背包中的逆向思维
- 完全背包基本实现
- 最长递增子序列(LIS)
- C++中cin、cin.get()、cin.getline…
- scanf()与gets()的冲突
- 最长公共子序列(LCS)
- 01背包问题
- 新的开始
- with check option
- U盘安装CentOS+Windows 7双系统
- 小析MBR、boot、GRUB的关系
- android多点触控统一的原理(使用event.getAction()&MotionEvent.ACTION_MASK的原因)
- C语言的那些秘密之---函数返回局部…
- 获取存储过程返回值
- C++中的四舍五入方法
- 存储过程与函数的区别