杭电2602---01背包

                                 骨收集器

http://acm.hdu.edu.cn/showproblem.php?pid=2602

问题描述

许多年前,在泰迪的家乡有一个叫“拾骨者”的人。这个人喜欢收集不同的骨头,比如狗,牛,他还去了坟墓…
骨收集器有一大袋的体积V,以及访问收集有很多骨头,很明显,不同的骨骼有不同的价值和不同的体积,现在考虑到每个骨头的价值以及他的旅行,你能计算出最大的总价值骨头收集器可以得到什么?

输入

第一行包含一整数T。
其次是T的情况下,每种情况下三行,第一行包含两个整数N,V,V(N < = 1000,< = 1000)代表骨骼的数量和他的包的体积。和第二行包含N个整数代表每个骨头的价值。第三行包含N个整数代表每个骨头的体积。

输出

每行一个整数代表最大的总价值(这个数字将低于231)。

样例输入

1
5 10
1 2 3 4 5
5 4 3 2 1

样例输出

14

01背包的思想参看:http://www.cnblogs.com/tanky_woo/archive/2010/07/31/1789621.html

代码1:

# include <iostream>
# include <cstdio>
# include <cstring>
# include <algorithm> 
using namespace std;

int back(int *w,int *v,int n,int m);

int f[1009][1009];//保存状态

int main(){

    int w[1009];//价值 
    int v[1009];//体积
    int i,j,T,n,m;//n表示物品的个数,m表示背包的体积 


    while(scanf("%d",&T)!=EOF){

        while(T--){
            memset(w,0,sizeof(w));
            memset(v,0,sizeof(v));

            scanf("%d%d",&n,&m);

            for(i=1;i<=n;i++){
                scanf("%d",&w[i]);
            }
            for(i=1;i<=n;i++){
                scanf("%d",&v[i]);    
            }

            int max = back(w,v,n,m); 

             printf("%d\n",max);
        }

    }



    return 0;
}



int back(int *w,int *v,int n,int m){

    memset(f,0,sizeof(f));
    int i,j;
    for(i=1;i<=n;i++){//这里不能从0开始,式子里面有i-1所以从1开始 


         for(j=0;j<=min(v[i]-1,m);j++) f[i][j]=f[i-1][j];  

            for(j=v[i];j<=m;j++){//这里不能从0开始,因为j-v[i],所以要从v[i]开始 
                f[i][j] =  max(f[i-1][j],f[i-1][j-v[i]]+w[i]);    //(f[i-1][j]>f[i-1][j-v[i]]+w[i])?f[i-1][j]:(f[i-1][j-v[i]]+w[i]);
                 // cout<<"f["<<i<<"]["<<j<<"]="<<f[i][j]<<"    ";
            }

        // cout<<endl;
    }
    /*
        一件件东西放进去,对同一件东西,考虑每个总体积,考虑这个东西放不放,取放和不放之间的最大值
    */
    return f[n][m];
    return 0;
}

/*
    1
    5 10
    1 2 3 4 5
    5 4 3 2 1
    f[1][5]=1    f[1][6]=1    f[1][7]=1    f[1][8]=1    f[1][9]=1    f[1][10]=1
    f[2][4]=2    f[2][5]=2    f[2][6]=2    f[2][7]=2    f[2][8]=2    f[2][9]=3    f[2][10]=3
    f[3][3]=3    f[3][4]=3    f[3][5]=3    f[3][6]=3    f[3][7]=5    f[3][8]=5    f[3][9]=5    f[3][10]=5
    f[4][2]=4    f[4][3]=4    f[4][4]=4    f[4][5]=7    f[4][6]=7    f[4][7]=7    f[4][8]=7    f[4][9]=9    f[4][10]=9
    f[5][1]=5    f[5][2]=5    f[5][3]=9    f[5][4]=9    f[5][5]=9    f[5][6]=12    f[5][7]=12    f[5][8]=12    f[5][9]=12    f[5][10]=14
    14


5
5 10
1 2 3 4 5
0 0 0 0 0

5 10
1 2 3 4 5
0 0 1 0 0

5 0
1 2 3 4 5
0 0 1 0 0

5 3
1 2 3 4 5
0 0 1 2 3



5 10
1 2 3 4 5   价值 
5 5 5 5 5   体积 

3 5
6 5 4
1 5 4


3 5 
2 3 3
1 8 9


*/

代码2:

# include <iostream>
# include <cstdio>
# include <algorithm>
# include <cstring> 
using namespace std;

int back(int w[],int v[],int n,int m);

int f[1009];
int main(){

    int n,m,T;
    int i,j,k;
    int v[1009];//v代表大小 
    int w[1009];//w代表价值 

    while(scanf("%d",&T)!=EOF){

        while(T--){

            scanf("%d%d",&n,&m);
            for(i=1;i<=n;i++) scanf("%d",&w[i]);
            for(i=1;i<=n;i++) scanf("%d",&v[i]);


            int max_ = back(w,v,n,m);
            printf("%d\n",max_); 
        }

    }



    return 0;
}

int back(int w[],int v[],int n,int m){

    memset(f,0,sizeof(f));

    for(int i=1;i<=n;i++)
        for(int j=m;j>=v[i];j--)//不能写成 ,注意下标   for(int j=m;j>=0;j--)
            f[j] = max(f[j],f[j-v[i]]+w[i]);//上一层的f[j]与 f[j-v[i]]+w[i]比较 

    return f[m];
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值