HDU 2602 动态规划01背包
2016-04-16 15:34
274 查看
01背包的状态转换方程 f[i,j] = Max{ f[i-1,j-Wi]+Pi( j >= Wi ), f[i-1,j] }
f[i,j]表示在前i件物品中选择若干件放在承重为 j 的背包中,可以取得的最大价值。Pi表示第i件物品的价值。
决策:为了背包中物品总价值最大化,第 i件物品应该放入背包中吗 ?
【以上文字来源】【http://blog.csdn.net/mu399/article/details/7722810】
【以下题目来源】【http://acm.hdu.edu.cn/showproblem.php?pid=2602】
以下是一道最简单的01背包动态规划,几乎不用修改状态转移方程,然而还是有那么几个坑点。
Bone Collector
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)
Total Submission(s) : 4 Accepted Submission(s) : 3
Problem Description
Many years ago , in Teddy’s hometown there was a man who was called “Bone Collector”. This man like to collect varies of bones , such as dog’s , cow’s , also he went to the grave …
The bone collector had a big bag with a volume of V ,and along his trip of collecting there are a lot of bones , obviously , different bone has different value and different volume, now given the each bone’s value along his trip , can you calculate out the
maximum of the total value the bone collector can get ?
Input
The first line contain a integer T , the number of cases. Followed by T cases , each case three lines , the first line contain two integer N , V, (N <= 1000 , V <= 1000 )representing the number of bones and the volume of his bag. And the second line contain
N integers representing the value of each bone. The third line contain N integers representing the volume of each bone.
Output
One integer per line representing the maximum of the total value (this number will be less than 2[sup]31[/sup]).
Sample Input
1
5 10
1 2 3 4 5
5 4 3 2 1
Sample Output
14
<pre name="code" class="cpp">#include<stdio.h> #include<string.h> int dp[1010][1010]; //状态储存 struct bone{ //结构体数组,储存骨头的价值和体积 int value; int volume; }bon[1010]; int max(int a,int b) //比较函数 { if(a>=b) return a; return b; } int main() { int T; scanf("%d",&T); while(T--) { int n,v; int i,j; scanf("%d%d",&n,&v); for(i=1;i<=n;i++) scanf("%d",&bon[i].value); for(i=1;i<=n;i++) scanf("%d",&bon[i].volume); memset(dp,0x0, sizeof(dp)); //这边二维数组的赋值也要高亮。 for(i=1;i<=n;i++) //这两个循环上面的0和1挺重要的。原因如下① { for(j=0;j<=v;j++) { if(j-bon[i].volume<0) //高亮,不太明白为什么有些旁友们不加这句话怎么会对QAQ dp[i][j]=dp[i-1][j]; else dp[i][j]=max(dp[i-1][j-bon[i].volume]+bon[i].value,dp[i-1][j]); } } /* for(i=0;i<=n;i++) //打表 { for(j=0;j<=v;j++) printf("%d ",dp[i][j]); printf("\n"); }*/ printf("%d\n",dp [v]); } return 0; }
①一开始我为了方便所以就两层都从1开始,导致了坑点1、测试组里面居然存在没有体积但是有价值的骨头????excuse me??
测试组1的打表
输入
15 10
1 2 3 4 5
5 4 3 2 1
DP[][]
骨头\体积 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 |
2 | 0 | 0 | 0 | 0 | 2 | 2 | 2 | 2 | 2 | 3 | 3 |
3 | 0 | 0 | 0 | 3 | 3 | 3 | 3 | 5 | 5 | 5 | 5 |
4 | 0 | 0 | 4 | 4 | 7 | 7 | 7 | 7 | 7 | 9 | 9 |
5 | 0 | 5 | 5 | 9 | 9 | 9 | 12 | 12 | 12 | 12 | 14 |
输出
14测试组2的打表(存在骨头体积为0但有价值)
输入
1 5 0 2 4 1 5 1 0 0 1 0 0
DP[][]
骨头\体积 | 0 | |
0 | 0 | |
1 | 2 | |
2 | 6 | |
3 | 6 | |
4 | 11 | |
5 | 12 |
输出
12
相关文章推荐
- C#使用回溯法解决背包问题实例分析
- 关于背包问题的一些理解和应用
- C++动态规划之最长公子序列实例
- C++动态规划之背包问题解决方法
- C#使用动态规划解决0-1背包问题实例分析
- 动态规划
- C++ 动态规划
- DP(动态规划) 解游轮费用问题
- 动态规划的用法——01背包问题
- 动态规划的用法——01背包问题
- 《收集苹果》 动态规划入门
- 《DNA比对》蓝桥杯复赛试题
- 《背包问题》 动态规划
- 自顶向下动态规划解决最长公共子序列(LCS)问题
- 初学ACM - 半数集(Half Set)问题 NOJ 1010 / FOJ 1207
- 关于爬楼梯的动态规划算法
- 动态规划 --- hdu 1003 **
- DP问题各种模型的状态转移方程
- 91. Decode Ways 动态规划-极客学院
- 动态规划系列【2】最长递增子序列LIS