01背包入门啦………
来源:互联网 发布:电脑拨号软件 编辑:程序博客网 时间:2024/06/08 07:08
作为动态规划中最为基础的内容,需要掌握、熟练,这就是必须的啦
那好,我们先看看什么才是01背包
先由一个最为经典的例题来引我们入门:
小喵有N个物品和一个背包。物品i的重量是Wi , 其价值位Vi,背包的容量为C。问小喵应该如何选择装入背包的物品,使得装进背包的物品的总价值为最大?
显而易见,贪心这位并不能帮助我们,我们只能新认识一位朋友,动态家族的01背包。
这位新朋友告诉我们,这个问题很简单,只需要一个个考虑这第i个物品是要还是不要。
现在看一下伪代码(:
for(i从1开始遍历N个物品)
for(j从C开始遍历,直到 j < Wi)
dp[ j ] = max( dp[ j ], dp[j-Wi]+V[i])
我们来分析一下代码:
dp[j]表示没有加进物品 i 时,重量为 j 时此刻的价值的最大值;
dp[j-Wi]+V[i]表示将第 i 个物品加进背包后重量为 j 时的价值;
之后判定此时总量为 j 时的最大价值dp[ j ];
如果现在似懂非懂,那你需要一些简单的例题来捋一下你的思路
[Bone Collector]http://acm.hdu.edu.cn/showproblem.php?pid=2602
简单的01背包:告诉你骨头的数量和背包的最大承受量,之后是每个骨头的价值和每个骨头的重量。求背包所能装的最大价值
#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <cstdlib>#include <string>using namespace std;int T;int val[1100], vol[1100];int dp[1100];void init(){ memset(val, -1, sizeof(val)); memset(vol, -1, sizeof(vol)); memset(dp, 0, sizeof(dp));}int main(){ int N, V; int i, j, k; while(~scanf("%d", &T)) { while(T--) { init(); scanf("%d%d", &N, &V); for(i = 0; i < N; i++) { scanf("%d", &val[i]); } for(i = 0; i < N; i++) { scanf("%d", &vol[i]); } for (i = 0; i < N; ++i) { for (j = V; j >= vol[i]; j--) { dp[j] = max(dp[j], dp[j-vol[i]]+val[i]); } } printf("%d\n", dp[V]); } } return 0;}
[Super Jumping! Jumping! Jumping!]http://acm.hdu.edu.cn/showproblem.php?pid=1087
棋盘游戏,从开始跳到结束截止,每一格都有一个值,你只能跳到比自己所在一格值大的格(开始和结束格不算),求游戏结束后的最大值。这一题的难处应该是它没有背包的最大承受量吧。
#include <iostream>#include <cstdio>#include <algorithm>#include <cstdlib>#include <string>#include <vector>#include <cstring>#define Max 2900using namespace std;int score[Max];int dp[Max], sum;int main(){ int N; int i, j, k; while(~scanf("%d", &N) && N) { memset(score, 0, sizeof(score)); memset(dp, 0, sizeof(dp)); for(i = 1; i <= N; i++) { scanf("%d", &score[i]); } dp[0] = 0; k = 0; for(i = 1; i <= N; i++) { sum = score[i]; for(j = 1; j < i; j++) { if(score[i] > score[j]) sum = max(sum, dp[j]+score[i]); } dp[i] = sum; k = max(k, sum); } cout << k << endl; } return 0;}
[命运]http://acm.hdu.edu.cn/showproblem.php?pid=2571
和hdu的1087差不多,不过这个是二维的图,运动方式三种向下一格,向右一格或向右跳现在所在格行的倍数。(!!!中文题)
#include <iostream>#include <cstdio>#include <algorithm>#include <cstdlib>#include <cstring>#include <string>using namespace std;int maza[21][1100];int dp[21][1100];int main(){ int T; int N, M; int i, j, k; bool a; scanf("%d", &T); while(T--) { scanf("%d%d", &N, &M); for(i = 1; i <= N; i++) { for(j = 1; j <= M; j++) { scanf("%d", &maza[i][j]); } } for(i = 1; i <= N; i++) { for(j = 1; j <= M; j++) { if(i == 1 && j == 1) dp[1][1] = maza[1][1]; else { a = false; if(i-1 >= 1) { dp[i][j] = dp[i-1][j] + maza[i][j]; a = true; } if(j-1 >= 1) { if(a) dp[i][j] = max(dp[i][j], dp[i][j-1]+maza[i][j]); else dp[i][j] = dp[i][j-1] + maza[i][j]; a = true; } for(k = 1; k < j-1; k++) { if(j%k != 0) continue; else { dp[i][j] = max(dp[i][j], dp[i][k]+maza[i][j]); } } } } } cout << dp[N][M] << endl; } return 0;}
请大家多多指教^^
- 01背包入门啦………
- 开学啦,读书啦,逃课啦……
- 背包入门--01背包
- 投票啦……
- 放假啦……
- 又发呆啦……
- 01背包入门
- 背包入门 01背包 hdu 2546
- 背包入门 01背包 hdu 2955 Robberies
- 背包问题入门 01背包和完全背包
- 要毕业啦…………
- LOGO开始投票啦……
- 马上就要二十六啦……
- 改用VirualBox啦,嘿嘿……
- 开始写博客啦……
- A - Reconnaissance 2 士兵 立正啦…
- 【01背包专题】--入门思考
- HDU2546饭卡 01背包入门
- CoreData的使用
- 杭电1282-回文
- CentOS6.3虚拟机配置安装
- ThinkPHP如何禁止直接通过路径访问
- java同步器之F4
- 01背包入门啦………
- android编程取消标题栏方法(appcompat_v7、NoTitleBar,2.3版本等)
- MYSQL查询SQL的注意事项和一些技巧总结
- java 为什么wait(),notify(),notifyAll()必须在同步方法/代码块中调用?
- sftp与samba文件传输速度的对比
- 统计损失
- linux中shell变量$#,$@,$0,$1,$2的含义
- Huatuo's Medicine
- 带你从源码角度理解Volley实现原理