hdu 2602 Bone Collector 01背包

来源:互联网 发布:java随机读取数组的值 编辑:程序博客网 时间:2024/06/06 12:55

暑假开始了对动态规划的学习

第一课背包问题之一(0-1背包)

例题 hdu 2602 Bone Collector


问题描述
许多年前,在泰迪的家乡,有一个人被称为“骨收藏家”。这个人喜欢收集不同的骨头,比如狗,牛,他还去了坟墓…
骨头收集者有一大袋的体积V,在他收集的过程中有很多骨头,很明显,不同的骨骼有不同的价值和不同的体积,现在考虑到每个骨头的价值以及他的旅行,你能计算出骨收集器能得到的最大值吗?
输入
第一行包含一个整数T,即案例数。
接着是T的情况,每一种情况下三行,第一行包含两个整数N,V,(N < = 1000,V < = 1000),代表骨头的数量和袋子的体积。
第二行包含N个整数表示每根骨头的值。
第三行包含代表每根骨头体积的N个整数。


输出
每一行的一个整数,表示总值的最大值(这个数字小于2^31)。


样例输入
Sample Input
1
5 10
1 2 3 4 5
5 4 3 2 1




样例输出
Sample Output
14



代码1正常


#include<cstdio>#include<cstring>#define mmax(a,b) a>b?a:bint c[1005],w[1005];int f[1005][1005];int main(){    int T;    scanf("%d",&T);    while(T--){        memset(f,0,sizeof(f));        int n,v;        int i,j;        scanf("%d%d",&n,&v);        for(i=1;i<=n;i++) scanf("%d",&w[i]);        for(i=1;i<=n;i++) scanf("%d",&c[i]);        for(i=1;i<=n;i++)            for(j=0;j<=v;j++){                if(c[i]<=j)f[i][j]=mmax(f[i-1][j],f[i-1][j-c[i]]+w[i]);                else                    f[i][j]=f[i-1][j];            }        printf("%d\n",f[n][v]);    }    return 0;}

比较两个粉色数组的大小得出蓝色数组(是否增加第f[i]个)

实际上用一维数组就可以解决这个问题,只需要下面一行覆盖掉上面一行就可以了,但是得从右向左来进行运算,因为得由左面一个数和上面一个数来推知需要求的解。

代码如下:

代码 2滚动数组(进行优化)


#include<cstdio>#include<cstring>#define mmax(a,b) a>b?a:bint ai[1050],bi[1050];int dp[1050];int main(){    int T;    int n,v;    int i,j;    scanf("%d",&T);    while(T--){        scanf("%d%d",&n,&v);        memset(dp,0,sizeof(dp));        for(i=1;i<=n;i++) scanf("%d",&ai[i]);        for(i=1;i<=n;i++) scanf("%d",&bi[i]);        for(i=1;i<=n;i++){            for(j=v;j>=bi[i];j--){                dp[j]=mmax(dp[j],dp[j-bi[i]]+ai[i]);            }        }            printf("%d\n",dp[v]);    }    return 0;}



比较两个粉色数组的大小得出蓝色数组(是否增加第i个)

希望我的思路对和我一样的初学者有所帮助。