HDU_2602 Bone Collector
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 49986 Accepted Submission(s): 20965
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
1
5 10
1 2 3 4 5
5 4 3 2 1
Sample Output
14
分析:裸01背包。
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2602
代码:(DFS超时)
#include<iostream> using namespace std; const int maxnum = 1005; int N, V; int Max_Value = 0; int value[maxnum]; int volume[maxnum]; //DFS未优化 一个物品选择放和不放 void DFS_Bag(int index, int sum_value, int sum_volume) { if (index == N) { return; } //not load current thing to bag DFS_Bag(index + 1, sum_value, sum_volume); if (sum_volume + volume[index] <= V) { if (sum_value + value[index] > Max_Value) { Max_Value = sum_value + value[index]; } //load current thing to bag DFS_Bag(index + 1, sum_value + value[index], sum_volume + volume[index]); } } //DFS优化 放当前物品之前检验背包容量是否超过V /* void DFS_Bag(int index, int sum_value, int sum_volume) { if (index == N) { if (sum_volume <= V&&sum_value > Max_Value) { Max_Value = sum_value; //cout << Max_Value<<endl; } return; } //not load current thing to bag DFS_Bag(index + 1, sum_value, sum_volume); //load current thing to bag DFS_Bag(index + 1, sum_value + value[index], sum_volume + volume[index]); }*/ int main() { int T; int i, j; cin >> T; while (T--) { cin >> N>>V; for (i = 0; i < N; i++) { cin >> volume[i]; } for (i = 0; i < N; i++) { cin >> value[i]; } DFS_Bag(0, 0, 0); cout << Max_Value << endl; } return 0; }
DP解法:
#include<stdio.h> #include<iostream> #include<string.h> using namespace std; long long max(long long num1,long long num2)//比较函数 { return num1>num2?num1:num2; } long long dp[1005][1005];//定义背包数组 int main() { int t;//数据组数 int m_bone,m_volume; int bone[1005], volume[1005]; cin >> t; while (t--) { int i, j, k; memset(dp, 0, sizeof(dp)); memset(bone,0,sizeof(bone)); memset(volume, 0, sizeof(volume)); cin >> m_bone >> m_volume; for (i = 1; i <= m_bone; i++) cin >> bone[i]; for (j = 1; j <= m_bone; j++) cin >> volume[j]; for (i = 1; i <= m_bone; i++) { for (j = 0; j <= m_volume; j++) { if (j < volume[i]) { dp[i][j] = dp[i - 1][j]; continue; } else { dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - volume[i]] + bone[i]); } } } cout << dp[m_bone][m_volume] << endl; } return 0; }
动态规划2:
#include<iostream> #include<stdlib.h> #include<string.h> using namespace std; const int maxnum = 1005; int N, V; int Max_Value = 0; int value[maxnum]; int volume[maxnum]; int dp[maxnum]; #define max(x,y)(x)>(y)?(x):(y); //动态规划解 int DP() { int i, j; memset(dp, 0, sizeof(dp)); for (i = 0; i < N; ++i)//N件物品 { for (j = V; j>=volume[i]; --j) { dp[j] = max(dp[j - volume[i]] + value[i], dp[j]);//装入物品 } } return dp[V]; } int main() { int T; int i, j; cin >> T; while (T--) { cin >> N>>V; for (i = 0; i < N; i++) { cin >> value[i]; } for (i = 0; i < N; i++) { cin >> volume[i]; } cout << DP() << endl; } return 0; }
dp3
#include<iostream> #include<stdlib.h> #include<string.h> using namespace std; const int maxnum = 1005; int N, V; int Max_Value = 0; int value[maxnum]; int volume[maxnum]; long long dp[maxnum][maxnum]; #define max(x,y)(x)>(y)?(x):(y); void DP() { int i, j; for (i = 1; i <= N; i++) { for (j = 0; j <= V; j++)//注意j从0开始 { if (volume[i]>j)//如果装不下 { dp[i][j] = dp[i-1][j]; } else//能装下 { if (dp[i - 1][j]>dp[i-1][j - volume[i]] + value[i])//不装价值大 { dp[i][j] = dp[i - 1][j]; } else//前i-1个物品的最优解与第i个物品的价值之和更大 { dp[i][j] = dp[i-1][j - volume[i]] + value[i]; } } } } cout << dp[N][V] << endl; } int main() { int T; int i, j; cin >> T; while (T--) { cin >> N>>V; for (i = 1; i <= N; i++) { cin >> value[i]; } for (i = 1; i <= N; i++) { cin >> volume[i]; } DP(); } return 0; }