它这个问题问的是,在有限的容量下,能装下的最大价值是多少。

所以我们可以递归求解,记忆性递归,用二维数组,但是这样的话就会超内存,所以我们只能用动规来写,而且不能开二维数组,

只能用滚动数组。

我们设一个F数组,大小为13000,它存的是容积为m的背包可放下的最大价值。

我们先假设一个二维数组F [ i ][ j ] ,它表示的意思是,背包里放 i 个物品,最大价值为 j ,它的最大价值。

我们可以知道 F [ i ][ j ] = max ( F [ i-1][ j ] ,F[ i-1][ j-w[i] ] +value [ i ] ) 。

它的意思是,F [ i ][ j ]的值来自于如果不选第 i 个物品,放下值为 j 的包的最大价值,和如果选第 i 个物品,背包里放下 j-weight[i] 大小物品的最大价值和第 i 个物品价值之和,经过比较之后最大的那个值。

我们对于F [ i ][ j ]可以选也可以不选,不选的话,它的价值就是F [ i-1 ][ j ] ,选的话它的价值就是F[ i-1][ j-w[i] ] +value [ i ] ,就是在原背包容积减去 i 物品的重量之后,放入 i-1 个物品的最大价值与 i 物品的价值之和。

不过有个条件,如果 j-w[i] >=0 ,我们才比较求解,小于它的话,我们就让它等于它的上一行同列的值。

好,那么问题来了,这个问题怎么在一维数组中求解呢?

首先我们要知道,在二维数组里面它们的形态:

F[ i-1][ j-w[i] ]                   F [ i-1][ j ]

F [ i ][ j ]                                F[ i ][ 2j-w[i] ]

所以说,对于F [ i-1 ][ j ] ,我们还是有用的,我们要用来求右下角的那个元素,我们不能正向,由小到大直接把F [ i-1 ][ j ]覆盖掉,我们应该在用完它时候,再覆盖掉,所以我们从右向左求,就不会伤害任何值了。

代码如下:

#include <iostream>
using namespace std;
int w[3600],d[3600],F[13000];
int main()
{
int n,m;
cin>>n>>m;
for (int i=1;i<=n;i++) {
cin>>w[i]>>d[i];
}
for (int i=1;i<=n;i++) {
for (int j=m;j>=w[i];j--) {
F[j]=max(F[j],F[j-w[i]]+d[i]);
}
}
cout<<F[m]<<endl;
return 0;
}

最新文章

  1. 懒加载插件- jquery.lazyload.js
  2. Python 2.7_Second_try_爬取阳光电影网_获取电影下载地址并写入文件 20161207
  3. shell script 学习笔记-----命令执行
  4. java分页
  5. Java优先级队列
  6. avoid null value in field
  7. C语言中的volatile
  8. jQuery工具函数下
  9. Java IO面试
  10. Java模拟新浪微博登陆抓取数据
  11. go学习(二)目录管理
  12. Python操作SQLAchemy
  13. Android中使用SVG矢量图(一)
  14. ajax提交数据
  15. Docker-Linux环境安装
  16. Thinkphp生成的验证码不显示——解决方法
  17. Ubuntu 安装 Docker CE(社区版)
  18. [Linux] deepin安装node
  19. 4-HTML Computer Code Elements
  20. angular笔记_8(事件)

热门文章

  1. Python 爬虫面试题 170 道:2019 版
  2. Android课程设计第四天ListView运用
  3. Distance in Tree CodeForces - 161D
  4. 字符串处理 Codeforces Round #297 (Div. 2) B. Pasha and String
  5. Closures闭包
  6. 将php数组传递到js—json_encode(),json_decode()
  7. Retrofit Upload multiple files and parameters
  8. 【ADO.NET】 基础 (SQL Server)
  9. Split方法,拆分字符串后,去除返回的空值
  10. c#自定义鼠标形状