动态规划 是对解最优化问题的一种途径 它往往是针对一种最优化问题 根据问题的不同性质 确定不同的设计方法 
因为这篇文章我想说点关于背包问题的事情 所以不再过多介绍动态规划 
背包问题 是动态规划中的一个经典题型 在联赛中也经常出现 其基本问题主要分为01 完全 多重 三种 
下面就通过程序与例题分别来说一下三种基本问题

01背包

有n件物品和容量为m的背包 给出i件物品的重量以及价值 求解让装入背包的物品重量不超过背包容量 且价值最大 
特点 这是最简单的背包问题 特点是每个物品只有一件供你选择放还是不放

对于这个问题一般有两种解法 下面分别来介绍一下

① 二维解法 
设f[i][j]表示前i件物品 总重量不超过j的最大价值 可得出状态转移方程 
f[i][j]=max{f[i-1][j-a[i]]+b[i],f[i-1][j]}

或许到这里大家对这个方程还不是那么熟悉,我们便通过一个实例来走一遍:

物品件数n=4,背包容量m=8

物品编号 1 2 3 4
w(体积)
v(价值)

初始化: 
 
总表: 

现在挑几个典型的说一下这个表是怎么更新的: 
点(i=2,j=3):这时有两个物品可以放入,背包容量为3,此时我们面临一个抉择,放还是不放第二件物品,我们看一下,上一状态,也就是只有一件物品或者说我们不放这件物品时的最大价值(i=1,j=3)为3,再看一下如果我们放这件物品的最大价值,(此时空间明显不足以同时放入这两件物品,我们如果放这件物品总得给它留出足够的空间吧,所以我们计算一下当给他留出足够空间时,空间还剩多少,此时背包的最大价值是多少)(i=1,j=3-3=0)为0(也就是说此时我如果想放入第二件物品的话,就得把第一件物品拿出来,拿出来后背包价值是0),再把第二件物品放进去,此时背包价值为4,我们比较一下这两个状态,如果不放第二件物品背包价值为3,放第二件物品背包价值为4,我们当然选择翻入第二件物品。 
如果这个点还是不太明白我们再试一个点,算法是一样的 
点(i=3,j=7):这时有三个物品可以放入,背包容量为7,我们面临一个抉择,放还是不放第三个物品,

这个地方我一开始有点迷,点(i=3,j=6)的时候我已经把第三个物品放进去了,那还这个点我还
看放不放他干啥,这时候不还得判断是不是得扔哪个物品吗?是不是有点傻?这时候我们的上一状
态是背包容量为j时,有两个物品可放的最大价值,可以说i相等时,每个点都是独立的,互不相
关,所以此时我们比较的是(i=2,j=7)这个点,要看的是,当有二个物品可以放入,背包容量为7
时再放入第三个物品能不能使背包的价值更大。

我们看一下,上一状态,也就是只有一件物品或者说我们不放这件物品时的最大价值(i=2,j=7)为7,再看一下如果我们放这件物品的最大价值,(此时空间明显不足以同时放入这两件物品,我们如果放这件物品总得给它留出足够的空间吧,所以我们计算一下当给他留出足够空间时,空间还剩多少,此时背包的最大价值是多少)(i=2,j=7-4=3)为4((重点理解!!!)也就是说要想放入第三个物品得给给他让出v[3]=4的容量,此时背包容量还剩3,我们可以知道,背包容量为3时背包最大价值为(i=2,j=3)=4),再把第三件物品放进去,此时背包价值为4+5=9,我们比较一下这两个状态,如果不放第三件物品背包价值为7,放第二件物品背包价值为9,我们当然选择翻入第三件物品。

代码如下

#include<iostream>
using namespace std;
int main()
{int m,n;cin>>n>>m;int a[50001],b[50001];int f[5001][5001];for(int i=1;i<=n;i++)cin>>a[i]>>b[i];for(int i=1;i<=n;i++)for(int j=m;j>0;j--){if(a[i]<=j)f[i][j]=max(f[i-1][j],f[i-1][j-a[i]]+b[i]);else f[i][j]=f[i-1][j];}cout<<f[n][m]<<endl; //最优解//COYG
}

虽然“原理”没有错 但是f数组开的太大 (一般应该5000就顶头了) 
在一些情况下 题目的数据会很大 因此f数组不开到一定程度是没有办法ac的 那么该怎么办呢 于是

②一维解法 
设f[j]表示重量不超过j公斤的最大价值 可得出状态转移方程

fj=maxj{fj,f[j−a[i]]+b[i]}fj=maxj{fj,f[j−a[i]]+b[i]}

代码如下

#include<iostream>
using namespace std;
int main()
{int n,m;cin>>n>>m;int a[50001],b[50001];          for(int i=1;i<=n;i++)cin>>a[i]>>b[i];int f[50001]={0};for(int i=1;i<=n;i++){       for(int j=m;j>=a[i];j--)if(f[j-a[i]]+b[i]>f[j])f[j]=f[j-a[i]]+b[i];  }cout<<f[m]<<endl;   //最优解//COYG
} 

这样用一维数组代替二维数组就解决了很多问题 所以用一维数组解决01背包是很重要的

01背包的例题有:[USACO07DEC]手链Charm Bracelet(洛谷搜索 P2871) 采药(洛谷搜索 P1048) [Noip普及组2001]装箱问题(洛谷搜索 P1049)

完全背包

有n件物品和容量为m的背包 给出i件物品的重量以及价值 求解让装入背包的物品重量不超过背包容量 且价值最大 
特点 题干看似与01一样 但它的特点是每个物品可以无限选用

其实这个题也可以写二维和一维两种 但之前已经说过了二维的有一定局限 所以在此之介绍一维 
一维 
设f[j]表示重量不超过j公斤的最大价值 可得出状态转移方程

fj=maxj{fj,f[j−a[i]]+b[i]}fj=maxj{fj,f[j−a[i]]+b[i]}

代码如下

#include<iostream>
using namespace std;
int main()
{int n,m;cin>>n>>m;int a[50001],b[50001];int f[50001]={0};for(int i=1;i<=n;i++){cin>>a[i]>>b[i];}for(int i=1;i<=n;i++)for(int j=a[i];j<=m;j++){if(f[j-a[i]]+b[i]>f[j])f[j]=f[j-a[i]]+b[i];}cout<<f[m]<<endl;//最优解//COYG
}

大家有没有感觉代码很熟悉?每错 一维完全背包的代码与一维01背包的代码只在循环上有些差别 而且状态转移方程也一样

例题可以百度搜索收益(也叫投资) 
算了好人做到底我还是ctrl+v一下题目吧 
【题目描述】收益 (POJ 2063) 
“建太空梯进入太空要1兆亿?”魔法学院的院长瞪大了眼睛。 
“这只是基础设施的费用,后期还要……”墨老师掰着手指算。 
“哎呀,现在地主也很穷啊,学院的钱批下来就这么多,你想办法用这笔钱在债券市场上获得最大收益吧。”院长皱着眉头。 
简单来说,就是你有一笔钱,你要将这笔钱去投资债券,现在有d种债券,每种债券都有一个价值和年收益,债券的价值是1000的倍数,问你如何投资在n年后的获得最大收益。 
【输入格式】 
第一个为一个整数M,表示有M组数据。 
每组数据第一行有两个整数,表示初始资金(不超过50000)和年数n。 
每组数据第二行为一个整数d(1 ≤ d≤10),表示债券种类。 
随后d行每行有两个整数,表示该债券的价值和年收益。年收益不会超过债券价值的10%。 
所有数据不超过整型取值范围。 
【输出格式】 
每组数据,输出n年后获得的最大收益。 
【输入样例】 

10000 4 

4000 400 
3000 250 
【输出样例】 
14050

贴一下我这个题的代码

#include<iostream>
#include<cstring>
using namespace std;
int main()
{int m,y,n,d,ans=0,a[100001],b[100001];int f[100001]={0}; cin>>m;while(m--){cin>>y>>n;cin>>d;for(int i=1;i<=d;i++){cin>>a[i]>>b[i];}for(int o=1;o<=n;o++){for(int i=1;i<=d;i++)for(int j=a[i];j<=y;j++){f[j]=max(f[j-a[i]]+b[i],f[j]);}y+=f[y]; //每次都要累计memset(f,0,sizeof(f));}cout<<y<<endl;}return 0;
} //小蒟蒻代码丑
//COYG

多重背包

有n件物品和容量为m的背包 给出i件物品的重量以及价值 还有数量 求解让装入背包的物品重量不超过背包容量 且价值最大 
特点 它与完全背包有类似点 特点是每个物品都有了一定的数量

状态转移方程为:

f[j]=max{f[j],f[j−k∗a[i]]+k∗b[i]}f[j]=max{f[j],f[j−k∗a[i]]+k∗b[i]}

【输入样例】 
8 2 
2 100 4 
4 100 2 
【输出样例】 
400

代码如下

#include<iostream>using namespace std;
int main()
{int m,n;cin>>m>>n;int a[10001],b[10001],c[10001];for(int i=1;i<=n;i++){cin>>a[i]>>b[i]>>c[i];}int f[10001];for(int i=1;i<=n;i++)for(int j=m;j>=0;j--)for(int k=0;k<=c[i];k++){if(j-k*a[i]<0)break;f[j]=max(f[j],f[j-k*a[i]]+k*b[i]);}cout<<f[m]<<endl;//最优解
}

【动态规划】三种基本背包问题相关推荐

  1. 0-1背包问题详解(DP分支限界回溯三种方法)

    0-1背包 将n个项目的权重和值,放入一个容量为W的背包中,得到背包中最大的总价值.换句话说,给定两个整数数组val[0..n - 1]和wt [0 . .n-1],分别表示与n个项目相关的值和权重. ...

  2. 背包问题knapsack的三种解法(Python 和 C)

    最近研究了一下0-1背包问题,题目就不复述了,大家应该都知道的. 确切的说不是三种解法而是四种解法,下面我就一一写来. 0.枚举法 这种是最简单的一种做法,当然也是时间空间复杂度最大的方法,得到的肯定 ...

  3. java完全背包,一次性解决三种背包问题

    前言 首先,大概讲一下什么是"背包"问题:背包问题是指你有一个容量为V的背包,然后有n个物品在你面前,你要怎么装才能使得背包里的物品总价值最大.而每种物品是只有1个,还是有多个,亦 ...

  4. 背包九讲之四(混合三种背包问题)

    1 /* 2 将01背包,完全背包,和多重完全背包问题结合起来,那么就是混合三种背的问题 3 根据三种背包的思想,那么可以得到 4 混合三种背包的问题可以这样子求解 5 for(int i=1; i& ...

  5. 三种背包问题的例题(各一道)

    FIRST ---------------------- 1102 采药 2005年NOIP全国联赛普及组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目 ...

  6. 背包问题C++(三种类型初涉)

    背包问题大背景: 存在一批物品,属性有价值(value)和内存(cost) 背包有总内存 由此,我们可以列出装不同东西的递推表格(DP问题特性) 如下,有物品价值5,4,3,2,1 分别对应内存 1, ...

  7. 最大子段和——用蛮力算法,分治策略,动态规划算法三种求法(C语言)

    目录 一.题目 二.算法求解 1.蛮力算法 伪代码 算法分析 程序 2.分治策略 伪代码 算法分析 程序 3.动态规划算法 伪代码 算法分析 程序 一.题目 设A=<a1,a2,...,an&g ...

  8. 九种 0-1 背包问题详解

    目录 动态规划概念 问题1:0-1背包问题 问题2:完全背包问题 问题3:多重背包问题 问题4:混合背包问题 问题5:二维背包问题 问题6:分组背包问题 问题7:有依赖的背包问题 (困难) 问题8:背 ...

  9. 四种常见背包问题整理

    四种常见背包问题整理 四种常见背包问题包括:① 最优装配 ② 部分背包问题 ③ 01背包问题 ④ 完全背包问题 ① 最优装配 给出 n 个物体,重量分别为 wi,使总重量不超过容量 C 的情况下选择尽 ...

最新文章

  1. 【java排序】 归并排序算法、堆排序算法
  2. Halcon知识:如何用mfc显示halcon读入图象
  3. 每天一香蕉,长成螺纹钢
  4. Java实现选择排序及其优化
  5. Flask框架-蓝图系统
  6. MySQL GTID复制Slave跳过错误事务Id以及复制排错问题总结
  7. python自动测试相机_Python + Appium+ IOS自动化测试
  8. ORA-01427: 单行子查询返回多个行 出现原因及对应防止措施
  9. python客户端服务器_Python客户端和服务器ch
  10. 全国高校安徽考区计算机,关于做好2021年上半年全国高校(安徽考区)计算机水平考试报名工作的通知...
  11. 快速取得三位数的个位,十位,百位
  12. 通过ajax获取经纬度,通过百度地图获取经纬度
  13. 整理:状态机的编程思想
  14. arccatalog点要素显示不完_利用ArcCatalog 管理地理空间数据库
  15. Android 开发——环境搭建
  16. python-windows命令行启动appium及杀掉对应接口进程
  17. 微信小程序---快速上手云开发
  18. 手机芯片战争:英特尔追ARM 联发科战高通
  19. Is Sampling Heuristics Necessary in Training Deep Object Detectors? 论文笔记
  20. 英语四/六级作文模板

热门文章

  1. 使用LoadRunner对Web Services进行调用--Add Service Call
  2. 将RGB值转换为灰度值的简单算法(转)
  3. Visual C# 2008+SQL Server 2005 数据库与网络开发--9.1.1 SQL Server 2005中的XML功能
  4. 数据采集中的采样率、缓冲区大小以及,每通道采样数之间的关系
  5. FIR IIR滤波器的设计
  6. GDT、GDTR、LDT、LDTR的理解
  7. VNC与RDP的区别
  8. [ 云炬创业基础笔记]商业模式创新
  9. 科大星云诗社动态20210212
  10. python程序开子进程打包成exe文件运行炸内存原因剖析