博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
背包问题(01背包和完全背包)
阅读量:6261 次
发布时间:2019-06-22

本文共 2022 字,大约阅读时间需要 6 分钟。

  背包问题是一个经典的动态规划模型,容易描述,容易理解。背包问题可简单描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。01背包问题的特点是,每种物品仅有一件,可以选择放或不放。

01背包问题描述:

  有N件物品和一个容量为V的背包。第i件物品的重量是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的重量总和不超过背包容量,且价值总和最大。

写出状态转移方程:

  f[i][v]=max{f[i-1][v], f[i-1][v-c[i]]+w[i]}

f[i][v]:  前i件物品恰放入一个容量为v的背包可以获得的最大价值

f[i-1][v]:  前i-1件物品……(同上),即不放入第i件物品的情况

f[i-1][v-c[i]]+w[i]:  放入第i件物品的情况,放入后的 f[i][v] 应该等于前 i-1 件物品在容量为 v-c[i] 上的最大价值加上 w[i]

空间优化:

  f[i][v]=max{f[i-1][v], f[i-1][v-c[i]]+w[i]}

  观察黑色字体部分,发现二维数组完全可以用一维数组替代:

  f[v]=max{f[v], f[v-c[i]]+w[i]}

程序怎么写?循环如何写?

  首先考虑如果所有的物品都能放进去,那一定就是最大价值,如果只能放进去 i (i<N)件物品,那一定要选择一个最优策略,这个策略的结果是价值最大,而每个 i 的最优策略实际上又是基于 i-1 的最优策略的。根据分析写出如下循环

  for(i=0; i<N; ++i)

    for(v=V; v>w[i]; --v)  //逆序推能够保证 f[v-c[i]] 保存的是状态是 f[i-1][v-c[i]] ,也就是每个物品只被使用了一次;顺序的话 f[v-c[i]] 保存的是 f[i][v-c[i]] ,每个物品有可能被使用多次,也就是完全背包问题的解法。

      f[v]=max(f[v], f[v-c[i]]+w[i])

poj上的3264题就是一道简单的01背包问题,

我的代码如下:

View Code
1 #include 
2 #define max(x, y) ((x)>(y) ? (x) : (y)) 3 int w[3403]; 4 int d[3403]; 5 int f[13000]; 6 int main() 7 { 8 int i, j, n, m; 9 int nMax = 0;10 scanf("%d %d", &n, &m);11 for(i=0; i
=w[i]; --j)18 {19 //printf("%d %d %d %d %d %d %d\n", __LINE__, j, i, f[j], w[i], d[i], f[j-w[i]]+d[i]);20 f[j] = max(f[j], f[j-w[i]]+d[i]);21 }22 }23 printf("%d\n", f[m]);24 return 0;25 }

poj上1384是一道完全背包问题,不过该问题求解的最小值,跟求最大值的最主要区别是小心初始化状态数组

这里也给出代码:

View Code
1 #include 
2 #define min(x, y) ((x)<(y) ? (x) : (y)) 3 #define MAX_INT 10000000 4 int p[501]; 5 int w[501]; 6 int f[10001]; 7 int main() 8 { 9 int t;10 scanf("%d", &t);11 while(t--)12 {13 int i, j, E, F, n, W;14 for(i=0; i<10001; ++i)15 {16 f[i] = MAX_INT;//注意初始化17 }18 f[0] = 0; //注意初始化19 scanf("%d %d", &E, &F);20 scanf("%d", &n);21 W = F-E;22 for(i=0; i

 

 

转载于:https://www.cnblogs.com/favourmeng/archive/2012/09/06/2673426.html

你可能感兴趣的文章
java生成随机字符串uuid
查看>>
黄永成-thinkphp讲解-个人博客讲解26集
查看>>
Mongodb(2)创建数据库,删除数据库,创建集合,删除集合,显示文档内容
查看>>
Tomcat禁止显示目录和文件列表
查看>>
linux mmap 详解【转】
查看>>
注释中不允许出现字符串 "--"。
查看>>
client 如何找到正确的RegionServer(HBase -ROOT-和.META.表)
查看>>
协议森林16 小美的桌号(DHCP协议)
查看>>
简单的ajax封装
查看>>
PHP初学者必须掌握的10个知识点
查看>>
[Asp.Net]获取客户端ip和mac地址
查看>>
Arcengine设置坐标系(转载)
查看>>
php字符串操作集锦
查看>>
【WPF】C#代码动态改变控件的样式
查看>>
P1115 最大子段和
查看>>
【翻译自mos文章】检查$ORACLE_HOME是否是RAC的HOME的方法以及relink RAC的Oracle binary的方法...
查看>>
PHP函数篇详解十进制、二进制、八进制和十六进制转换函数说明
查看>>
php max_execution_time执行时间问题
查看>>
Hystrix系列-5-Hystrix的资源隔离策略
查看>>
005-ant design -结合echart
查看>>