Bone Collector
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 45005 Accepted Submission(s): 18733
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 ?
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.
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
动态规划(Dynamic Programming)一直是ACM的一个难点和重点。这是杭电的一道题,本质其实就是背包问题。一个简单的动态规划。
以下是算法导论里的一段描述:
动态规划算法的设计可以分如下四个步骤:
1)描述最优解的结构
2)递归定义最优解的值
3)按自底向上计算最优解的值
4)由计算出的结果构造一个最优解
#include<iostream> #include<cmath> #include<cstring> #include<algorithm> using namespace std; int p[1000][1000]; int main() { int T,N,M,i,j; int a[1000],b[1000]; while(cin>>T) while(T--) { cin>>N>>M;//M代表袋子的体积 for(i=1;i<=N;i++)//a用来存价值 cin>>a[i]; for(i=1;i<=N;i++)//b用来存体积 cin>>b[i]; memset(p,0,sizeof(p)); for(i=1;i<=N;i++) //N代表物品号 for(j=0;j<=M;j++) { if(b[i]<=j) p[i][j]=max(p[i-1][j],p[i-1][j-b[i]]+a[i]); else //物品体积大于袋子体积 p[i][j]=p[i-1][j]; } cout<<p[N][M]<<endl; /* 打表查看矩阵 cout<<endl<<endl; for(i=1;i<=N;i++) { for(j=0;j<=M;j++) { cout<<p[i][j]<<" "; } cout<<endl; } */ } return 0; }<strong> </strong>
这是本次输入输出打的表
其实程序就是从第一件物品开始选,袋子体积由0-10,再出现第二件物品继续选,袋子体积由0-10。。。直到结束。
本题的动态规划方程为:
f(n,m)=max{f(n-1,m), f(n-1,m-w[n])+v[n]}下面再给一个优化的代码:#include<iostream> #include<cmath> #include<cstring> #include<algorithm> using namespace std; int main() { int m,n,v,i,j; int a[1000],b[1000],p[1000]; while(cin>>m) while(m--) { cin>>n>>v; for(i=1;i<=n;i++) cin>>a[i]; for(i=1;i<=n;i++) cin>>b[i]; memset(p,0,sizeof(p)); for(i=1;i<=n;i++) for(j=v;j>=b[i];j--) p[j]=max(p[j],p[j-b[i]]+a[i]); cout<<p[v]<<endl; } return 0; }