动态规划学习之0-1背包和完全背包
2015-12-23 12:02
176 查看
背包问题大体上有三种类型,分别是0-1背包,完全背包和介于其中的背包问题。其中又有很多小的细节改变,比如说背包是否要求刚好装满。一般求解的是背包不要求刚好装满,只要求在限制范围内的最大价值就可以。
0-1背包的思路是这样的,不断地向背包添加物品,对于一个物品,当背包容量为v时,选择是添加当前物品进背包还是不添加直
接用前面的安排。V[j][C] = max{V[j-1][C],V[j-1][C-w[j]]+value[j] },表示选择不添加当前这个背包还是添加这个背包,对应的例子:
那么0-1背包的对应状态表应该为 C=5时:
一种最优化的时间,空间地方式是将存储状态改成一维数组,这个数组每次从C=max开始添加背包,这样C-W[i]就是上一个状态的值,可以保证每个背包只被添加一次。
对于完全背包C=1开始,这样C-W[I]就是可以被添加多次的此次被计算过的最大值。
完全背包上面的例子的状态应该是:
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 :
学习链接:http://wenku.baidu.com/view/82d6c300de80d4d8d15a4f8d.html#
http://wenku.baidu.com/link?url=19k7mBFMIMvDhkqqwwnZvoPLMLtVB88SG7Fd1tINVxSc1BeY46sVj02D64IO8a-mqfcN4_tI9Q4OP_7xIVQz64q5tvntiMuk6yWSiUzIp8q
0-1背包的思路是这样的,不断地向背包添加物品,对于一个物品,当背包容量为v时,选择是添加当前物品进背包还是不添加直
接用前面的安排。V[j][C] = max{V[j-1][C],V[j-1][C-w[j]]+value[j] },表示选择不添加当前这个背包还是添加这个背包,对应的例子:
No | weight | value |
1 | 2 | 3 |
2 | 3 | 4 |
3 | 4 | 5 |
1 | 2 | 3 | 4 | 5 | |
1 | 0 | 3 | 3 | 3 | 3 |
2 | 0 | 3 | 4 | 4 | 7 |
3 | 0 | 3 | 4 | 4 | 7 |
对于完全背包C=1开始,这样C-W[I]就是可以被添加多次的此次被计算过的最大值。
完全背包上面的例子的状态应该是:
1 | 2 | 3 | 4 | 5 | |
1 | 0 | 3 | 3 | 6 | 6 |
2 | 0 | 3 | 4 | 6 | 7 |
3 | 0 | 3 | 4 | 6 | 7 |
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 ,weight ; 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 ,weight ; 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
相关文章推荐
- RMAN-05541: no archived logs found in target database
- PHP多维数组转一维数组的简单实现方法
- Looper、Handler应用---实现主线程向子线程发送消息
- 在Unity3D中加载外部图片的两种方法
- swift中实现UITableView总结二
- 对MySQL中字符集的相关设置操作的基本教程
- linux版本Debian VS CentOS
- GDB十分钟教程
- Kafka设计解析(四):Kafka Consumer解析
- Android AsyncTask异步任务解析
- 数组-slice、indexOf
- Javascript中apply、call、bind的区别
- C#线程篇---Windows调度线程准则
- Git小白 -- Eclipse插件EGit的使用
- jvm加载class原理
- hadoop 兼容问题
- 一念執著
- js 多setInterval冲突的解决方法
- 用canvas画一个钟表
- AD09之与AD6版本使用不同对比