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
题目大意:在一个固定大小的袋子里收集骨头,每个骨头有他的体积和价值问袋子装骨头的最大价值;
解题思路:0 1背包问题:
递推方式的代码:
#include<stdio.h>
#include<string.h>
int n,m;
int val[1100],v[1100];
int dp[1100][1100];
int maxx(int x,int y)
{
return x>y?x:y;
}
int sovle(int i,int j)
{
if(dp[i][j]>=0)
return dp[i][j];
int dd;
if(i==n)
dd=0;
else if(j<v[i])
{
dd=sovle(i+1,j);
}
else
dd=maxx(sovle(i+1,j),sovle(i+1,j-v[i])+val[i]);
return dp[i][j]=dd;
}
int main()
{
int N;
scanf("%d",&N);
while(N--)
{
scanf("%d%d",&n,&m);
memset(dp,-1,sizeof(dp));
int i;
for(i=0;i<n;i++)
scanf("%d",&val[i]);
for(i=0;i<n;i++)
scanf("%d",&v[i]);
printf("%d\n",sovle(0,m));
}
return 0;
}
由递推可以得到状态转移方程:
if(j<v[i])
dp[i+1][j]=dp[i][j];。
else
dp[i+1][j]=max(dp[i][j],dp[i][j-v[i]]+val[i]);
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int n,m;
int val[1100],v[1100];
int dp[1100][1100];
int maxx(int x,int y)
{
return x>y?x:y;
}
int main()
{
int N;
scanf("%d",&N);
while(N--)
{
scanf("%d%d",&n,&m);
memset(dp,0,sizeof(dp));
int i,j;
for(i=0;i<n;i++)
scanf("%d",&val[i]);
for(i=0;i<n;i++)
scanf("%d",&v[i]);
for(i=0;i<n;i++)
for(j=0;j<=m;j++)
{
if(j<v[i])
dp[i+1][j]=dp[i][j];
else
dp[i+1][j]=max(dp[i][j],dp[i][j-v[i]]+val[i]);
}
printf("%d\n",dp[n][m]);
}
return 0;
}
二维的dp转化为一维的;
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int n,m;
int val[1100],v[1100];
int dp[1100];
int maxx(int x,int y)
{
return x>y?x:y;
}
int main()
{
int N;
scanf("%d",&N);
while(N--)
{
scanf("%d%d",&n,&m);
memset(dp,0,sizeof(dp));
int i,j;
for(i=0;i<n;i++)
scanf("%d",&val[i]);
for(i=0;i<n;i++)
scanf("%d",&v[i]);
for(i=0;i<n;i++)
for(j=m;j>=v[i];j--)
{
dp[j]=max(dp[j],dp[j-v[i]]+val[i]);
}
printf("%d\n",dp[m]);
}
return 0;
}