hdu 2602 Bone Collector (01 背包问题)

Bone Collector

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2080    Accepted Submission(s): 669

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 31).
 

 

Sample Input
1
5 10
1 2 3 4 5
5 4 3 2 1
 

 

Sample Output
14
 
http://acm.hdu.edu.cn/showproblem.php?pid=2602
详细算法描述看 http://baike.baidu.com/view/1731915.htm?fr=ala0
最简单的递归法:(该算法会超时。)
// 时间复杂度是 2^n #include <iostream> #include <cmath> #include <cstring> #include <map> #include <algorithm> using namespace std; const int MAX = 1001; typedef struct { int value; int volume; }bone; bone b[MAX]; int make(int i, int j) // 第i个物品, 当前剩余容量j { if (i <= 0) return 0; int r1 = 0, r2 = 0; if (j >= b[i].volume)//第i个物品可以放入背包得到的价值 { r1 = make(i - 1, j - b[i].volume) + b[i].value; } r2 = make(i - 1, j);//第i个物品没有放入背包得到的价值 if (r1 > r2) return r1; else return r2; } int main() { freopen("in6.txt","r", stdin); int t, n, v; cin>>t; while (t--) { cin>>n>>v; for(int i = 1; i <= n; i++) { cin>>b[i].value; } for(int i = 1; i <= n; i++) { cin>>b[i].volume; } int t = make(n, v); cout<<t<<endl; } }
使用动态规划。 时间复杂度是 n*v (个数 * 容量), 空间复杂度 二维矩阵(n*v)  n*v 有可能大于 2^n
#include <iostream> #include <cmath> #include <cstring> #include <map> #include <algorithm> using namespace std; const int MAX = 1001; typedef struct { int value; int volume; }bone; bone b[MAX]; int f[MAX][MAX]; int main() { int t, n, v; cin>>t; while (t--) { cin>>n>>v; for(int i = 1; i <= n; i++) { cin>>b[i].value; } for(int i = 1; i <= n; i++) { cin>>b[i].volume; } for (int i = 0; i <= v; i++) { f[0][i] = 0; } for (int i = 1; i <= n; i++) { for (int j = 0; j <= v; j++) { f[i][j] = f[i-1][j]; if (j >= b[i].volume && f[i - 1][j - b[i].volume] + b[i].value > f[i][j]) f[i][j] = f[i - 1][j - b[i].volume] + b[i].value; } } cout<<f[n][v]<<endl; } }
简化矩阵的算法,时间复杂度同样是 n*v, 空间复杂度 一维数组(v)。
#include <iostream> #include <cmath> #include <cstring> #include <map> #include <algorithm> using namespace std; const int MAX = 1090; typedef struct { int value; int volume; }bone; bone b[MAX]; int dp[MAX]; int main() { //freopen("in6.txt","r", stdin); int t, n, v; cin>>t; while (t--) { memset(dp, 0, sizeof(dp)); cin>>n>>v; for(int i = 1; i <= n; i++) { cin>>b[i].value; } for(int i = 1; i <= n; i++) { cin>>b[i].volume; } for (int i = 1; i <= n; i++) { for (int j = v; j >= b[i].volume; j--) { if (dp[j] < dp[j - b[i].volume] + b[i].value) { dp[j] = dp[j - b[i].volume] + b[i].value; } } } cout<<dp[v]<<endl; } return 0; }

你可能感兴趣的:(算法,struct,Integer,less,each,output)