zoukankan      html  css  js  c++  java
  • bone collector hdu 01背包问题

    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 ?
     
    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 231).
     
    Sample Input
    1
    5 10
    1 2 3 4 5
    5 4 3 2 1
     
    Sample Output
    14
     

    先将原始问题一般化,欲求背包能够获得的总价值,即欲求前j个物体放入容量为m(kg)背包的最大价值f[j]——使用一个数组来存储最大价值,当j取10时,即原始问题了。而前i个物体放入容量为m(kg)的背包,又可以转化成前(i-1)个物体放入背包的问题。

    核心代码:

    for(i=0;i<n;i++)
                for(j=v;j>=bone[i].volume;j--)
                f[j]=max(f[j],f[j-bone[i].volume]+bone[i].value);

     f[j]=max(f[j],f[j-bone[i].volume]+bone[i].value);即为该问题的状态转移方程

    当i==0,bone[0].volume==5时经过一个循环

    f[10]=1;

    f[9]=1;

    f[8]=1;

    f[7]=1;

    f[6]=1;

    f[5]=1;

    f[4]=0;

    f[3]=0;

    f[2]=0;

    f[1]=0;

    f[0]=0;

    当i==1,bone[1].volume==4时经过一个循环

    f[10]=3;

    f[9]=3;

    f[8]=2;//因为飞f[4]==0,f[8]==1,而8-bone[1].volume==4,所以f[8]=max(f[8],f[j-bone[i].volume(4)]+bone[i].value(2));下面同理

    f[7]=2;

    f[6]=2;

    f[5]=2;

    f[4]=2;

    f[3]=0;//3<5也<4,所以前两个骨头都放不下,下面同理,上面也同理

    f[2]=0;

    f[1]=0;

    f[0]=0;

    当i==2,bone[2].volume==3时经过一个循环

    f[10]=5;

    f[9]=5;

    f[8]=5;

    f[7]=5;

    f[6]=3;

    f[5]=3;

    f[4]=3;

    f[3]=3;

    f[2]=0;

    f[1]=0;

    f[0]=0;

    当i==3,bone[3].volume==2时经过一个循环

    f[10]=9;

    f[9]=9;

    f[8]=7;

    f[7]=7;

    f[6]=7;

    f[5]=7;

    f[4]=4;

    f[3]=4;

    f[2]=4;;//在此j循环跳出,上面同理,下面也同理,f[j]>=2;

    f[1]=0;

    f[0]=0;

    当i==4,bone[3].volume==1时经过一个循环

    f[10]=14;

    f[9]=12;

    f[8]=12;

    f[7]=12;

    f[6]=12;

    f[5]=9;

    f[4]=9;

    f[3]=9;

    f[2]=5;;//在此j循环跳出,上面同理,下面也同理,f[j]>=2;

    f[1]=5;

    f[0]=0;

     代码实现:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 using namespace std;
     6 struct bone
     7 {
     8     int volume;
     9     int value;
    10 }bone[1005];
    11 int max(int a,int b)
    12 {
    13     return a>b?a:b;
    14 }
    15 int main()
    16 {
    17     int t,n,v,i,j,f[1005];
    18     while(cin>>t)
    19     {
    20         while(t--)
    21         {
    22             cin>>n>>v;
    23             for(i=0;i<n;i++)
    24             cin>>bone[i].value;
    25             for(i=0;i<n;i++)
    26             cin>>bone[i].volume;
    27             memset(f,0,sizeof(f));
    28             for(i=0;i<n;i++)
    29                 for(j=v;j>=bone[i].volume;j--)
    30                     f[j]=max(f[j],f[j-bone[i].volume]+bone[i].value);
    31             cout<<f[v]<<endl;
    32         }
    33     }
    34     return 0;
    35 }
  • 相关阅读:
    BZOJ4912 [Sdoi2017]天才黑客 【虚树 + 最短路】
    BZOJ2738 矩阵乘法 【整体二分 + BIT】
    BZOJ1185 [HNOI2007]最小矩形覆盖 【旋转卡壳】
    BZOJ4830 [Hnoi2017]抛硬币 【扩展Lucas】
    BZOJ3738 [Ontak2013]Kapitał 【扩展Lucas】
    云计算,大数据,人工智能
    conda基本操作
    nlp基础(一)基本应用
    ml交叉验证
    Python魔术方法
  • 原文地址:https://www.cnblogs.com/WHLdbk/p/5704087.html
Copyright © 2011-2022 走看看