F - Bone Collector HDU - 2602

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;
}

猜你喜欢

转载自blog.csdn.net/TANG3223/article/details/81274664