01背包、完全背包、最长上升子序列
来源:互联网 发布:chromebook ubuntu 编辑:程序博客网 时间:2024/06/05 03:13
1、01背包
题目
有N件物品和一个容量为V的背包。第i件物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。
例如:http://codevs.cn/problem/1014/
#include<iostream>#include<algorithm>using namespace std;//dp初值为0int dp[100000] = { 0 };int main() {//freopen("data.txt", "r", stdin);//M为背包最大体积,N表示物品数量int M, N;cin >> M >> N;//w表示第i件物品的重量,c表示第i件物品的价值int c, w;//i:1<=i<=N//j:w<=j<=M,M-w递减for (int i = 1; i <= N; i++) {cin >> c >> w;for (int j = M; j >= w; j--) {dp[j] = max(dp[j], dp[j - w] + c);}}cout << dp[M] << endl;return 0;}
有的题目要求“恰好装满背包”时的最优解,有的题目则并没有要求必须把背包装满。一种区别这两种问法的实现方法是在初始化的时候有所不同。
如果是第一种问法,要求恰好装满背包,那么在初始化时除了f[0]为0其它f[1..V]均设为-∞,这样就可以保证最终得到的f[N]是一种恰好装满背包的最优解。
如果并没有要求必须把背包装满,而是只希望价格尽量大,初始化时应该将f[0..V]全部设为0。
为什么呢?可以这样理解:初始化的f数组事实上就是在没有任何物品可以放入背包时的合法状态。如果要求背包恰好装满,那么此时只有容量为0的背包可能被价值为0的nothing“恰好装满”,其它容量的背包均没有合法的解,属于未定义的状态,它们的值就都应该是-∞了。如果背包并非必须被装满,那么任何容量的背包都有一个合法解“什么都不装”,这个解的价值为0,所以初始时状态的值也就全部为0了。
2、完全背包题目
有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
例如:http://codevs.cn/problem/2029/
#include<iostream>#include<algorithm>using namespace std;//dp初值为0int dp[100000] = { 0 };int main() {//freopen("data.txt", "r", stdin);//M为背包最大体积,N表示物品数量int M, N;cin >> M >> N;//w表示第i件物品的重量,c表示第i件物品的价值int c, w;//i:1<=i<=N//j:w<=j<=M,w-for (int i = 1; i <= N; i++) {cin >> c >> w;for (int j = w; j <= M; j++) {dp[j] = max(dp[j], dp[j - w] + c);}}cout << dp[M] << endl;return 0;}
3、最长上升子序列
某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数)
输出这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统。
389 207 155 300 299 170 158 65
6
2
分析这个题目可知,一个拦截系统能拦截导弹的最大数目就是输入序列中最长非递增子序列的长度,而拦截系统的数目就是输入序列中最长递增子序列的长度
#include<iostream> #include<algorithm> #include<stdio.h> using namespace std;int a[10010];int up[10010];int down[10010];int upans,downans=0;int main(){ int n=0; //读文件一直到文件结尾 while(cin>>a[n]){ up[n]=1; down[n]=1; n++; } //i:1~n //j:0~i for(int i=1;i<n;i++){ for(int j=0;j<i;j++){ //非递增 if(a[i]<=a[j])down[i]=max(down[i],down[j]+1); //递增 else up[i]=max(up[i],up[j]+1); } //更新 downans=max(downans,down[i]); upans=max(upans,up[i]); } cout<<downans<<endl<<upans<<endl; return 0; }
- 01背包、完全背包、最长上升子序列
- HHU暑期第四弹——动态规划入门(01背包+完全背包+多重背包+最长上升子序列和公共子序列)
- 01:最长上升子序列
- 01:最长上升子序列
- 01-最长上升子序列
- 01:最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 最长上升子序列
- 内核proc文件系统简介
- Oracle数据库各版本区别+字符集+OSDBA组+全局数据库名+管理(SYS)口令
- Mysql| distinct去除重复的结果(DISTINCT)
- 妈蛋。一下午就在腾讯云弄Nginx的配置,垃圾ubuntu
- 虚函数的多态实现小解
- 01背包、完全背包、最长上升子序列
- lodash
- HDU2003 求绝对值【入门】
- innerHTML和outerHTML的区别,jQuery删除节点的方法
- 并查集算法
- 当你的算法之路达到了瓶颈,what should I do?
- 笨办法学python习题18 命名、变量、代码和函数
- 刘明春总结2011.11.12 连续第十四天
- queue