ACM HDU Bone Collector 01背包
来源:互联网 发布:淘宝圣手魔方 编辑:程序博客网 时间:2024/05/19 21:59
Bone Collector
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 45490 Accepted Submission(s): 18925
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 231).
Sample Input
15 101 2 3 4 55 4 3 2 1
Sample Output
14
这是做的第一道01背包的题目。题目的大意是有n个物品,体积为v的背包。不断的放入物品,当然物品有各自的体积和价值。在不超过总体积v的情况下,问能够达到的最大价值。并且物品是一个一个放入的。最后若有剩余的体积也不会填满。
刚开始是用贪心做的。将价值与体积的比值设定为一个值,即单位价值。然后按照单位价值排序,挨个取物品,考虑到了体积为0的情况,就将单位价值设定为无穷大。但是这样做并不能保证最优解。例如:总体积为5,一共有两个物品。第一个体积4,价值6。第二个体积为2,价值为4。很明显第一个更合适,但是按照单位价值比来做。结果就不是这样的了。所以贪心法不适合这样的01背包。但是适合物品可以只取一部分的01背包,是的最后的背包肯定会被刚好填满。
在这道题中用数组dp来保存运算结果。例如dp[i][j]表示前i个物品放入体积为j的背包中。
判断第i个物品能否放入大小为j的背包中。如果可以,是放?还是不放?
如果放,相当于前i-1个物品放入大小为j-vol[i]的背包中,再加上价值为val[i]的第i个背包。如果不放,相当于前i-1个物品放入大小为j的背包中。即有dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - vol[i]] + val[i]);
如果不可以,相当于前i-1个物品放入大小为j的物品中。即有dp[i][j] = dp[i - 1][j];
重点是可以放的情况!
最后需要注意的是体积可以为0,同时最后结果保存在dp[n][v]中。
附上源代码:
#include<iostream>#include<stdio.h>#include<stdlib.h>#include<string>#include<string.h>#include<math.h>#include<map>#include<vector>#include<algorithm>using namespace std;#define MAX 0x3f3f3f3f#define MIN -0x3f3f3f3f#define N 1005int val[N];int vol[N];int dp[N][N];int main(){int T;int i, j;int n, v;//物品,背包体积scanf("%d", &T);while (T--){scanf("%d%d", &n, &v);for (i = 1; i <= n; i++)scanf("%d", &val[i]);for (i = 1; i <= n; i++)scanf("%d", &vol[i]);memset(dp, 0, sizeof(dp));for (i = 1; i <= n; i++){for (j = 0; j <= v; j++)//体积可以是0{if (vol[i] <= j)//第i个物品的体积可以放到大小为j的背包中dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - vol[i]] + val[i]);//如果不放,前i-1件物品放入大小为v的包中。放的话,前i-1件物品放入v-vol[i]大的背包中elsedp[i][j] = dp[i - 1][j];//放不进去的话,相当于前i-1件物品放入大小为v的背包中}}printf("%d\n", dp[n][v]);}return 0;}
顺便在附上错误的贪心代码,警告自己!
#include<iostream>#include<stdio.h>#include<stdlib.h>#include<string>#include<string.h>#include<math.h>#include<map>#include<vector>#include<algorithm>using namespace std;#define MAX 0x3f3f3f3f#define MIN -0x3f3f3f3fstruct node{int volume;int vaule;double f;}ans[1005];int cmp(const void *a, const void *b){struct node *aa = (node *)a;struct node *bb = (node *)b;return(((aa->f)<(bb->f)) ? 1 : -1);}int main(){int T;int N, V;int i;int val;//价值int vol;//体积scanf("%d", &T);while (T--){scanf("%d%d", &N, &V);for (i = 0; i < N; i++){scanf("%d", &ans[i].vaule);}for (i = 0; i < N; i++){scanf("%d", &ans[i].volume);if (ans[i].volume == 0)ans[i].f = MAX;elseans[i].f = ans[i].vaule*1.0 / ans[i].volume;}qsort(ans, N, sizeof(ans[0]), cmp);val = 0;vol = 0;ans[N].vaule = 0;ans[N].volume = 0;ans[N].f = 0;for (i = 0; i <= N; i++){if (vol <= V){val = val + ans[i].vaule;vol = vol + ans[i].volume;}else if (vol>V){val = val - ans[i - 1].vaule;//vol = vol - ans[i - 1].volume;//val = val + (V - vol)*(int)ans[i - 1].f;break;}}printf("%d\n", val);}return 0;}等等,这个问题还没完。我发现了什么。二维数组跟新的时候第二重for循环改成v~0结果,居然还能够AC,amazing!虽然不太明白原因,先上图。
1 0
- [ACM] hdu 2602 Bone Collector(01背包)
- ACM HDU Bone Collector 01背包
- ACM 杭电hdu 2602 Bone Collector(01背包)
- 【hdu】 Bone Collector 01背包
- hdu Bone collector(01背包)
- Bone Collector 01背包 HDU
- 01背包 Bone Collector HDU
- hdu 2602 (01 背包)Bone Collector
- hdu 2602 Bone Collector 01背包
- hdu 2602 Bone Collector 01背包
- hdu 2602 Bone Collector (01背包)
- hdu 2602 Bone Collector【01背包】
- hdu 2602 Bone Collector 简单01背包
- hdu 2602 Bone Collector(01背包)
- hdu 2602 Bone Collector (01背包)
- HDU 2602 Bone Collector(裸01背包)
- HDU 2602 Bone Collector( 01背包 )
- HDU 2602 Bone Collector(01背包)
- 求每个月的最后一天日期
- 问题汇总のUnable to find expected entry in Release file问题
- Cocos2d-x客户端代码加密
- myeclipse快捷键
- Is there any way to define a min and max value for edittext in android?
- ACM HDU Bone Collector 01背包
- bzoj 1103: [POI2007]大都市meg 树状数组
- linux build commands
- typedef详解
- js阻塞特性
- Arcgis for js,Openlayers中加载GeoJSON
- 2015蓝桥杯试题--三羊献瑞
- 3996: [TJOI2015]线性代数|最小割
- Spring核心概念理解-IoC容器、DI、AOP