HDU 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活

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

#include<stdio.h>

#include<stdlib.h>

void CompletePack( int price,int f[],int money,int weight )//完全背包

{

      for( int i=price; i<=money; i++ )

      {

           if( f[ i-price ]+weight>f[i] )

           {

           f[i]=f[i-price] + weight; 

           

           }    

      }   

}

void ZeroOnePack( int price,int num,int f[],int money,int weight )//01背包

{

        int t=num*weight,tt=num*price;

        for( int i=money; i>=tt;i-- )

        {

           if( f[ i-tt ]+t > f[i] )

           {

           f[i]=f[i-tt]+t;

           }

           }

                  

}

int DP( int price[],int weight[],int num[],int number ,int money)

{

    int f[124]={0};

     for( int i=1; i<=number ; i++ )

     {

          

          if( price[i]*num[i]>= money)

          {

               CompletePack( price[i],f,money,weight[i] );    

          }

          else 

          {

                 int k=1;

                 while( k<num[i] ) //2进制法

                 {

                      ZeroOnePack( price[i],k,f,money,weight[i] );

                      num[i]=num[i]-k;

                      k=k<<1;       

                 }

                 ZeroOnePack( price[i],num[i],f,money,weight[i] );      

          }     

     }

     return f[money];    

}

int main()

{

    int money,n,number,price[124],num[124],weight[124];

    scanf( "%d",&n );

    for( int i=0; i<n; i++ )

    {

        scanf( "%d%d",&money,&number );

        for( int j=1; j<=number ; j++ )

        {

           scanf( "%d%d%d",&price[j],&weight[j],&num[j] );    

        }

        printf( "%d\n",DP( price,weight,num,number,money ) );     

    }

    return 0;    

}

  

该题是要用一定的钱买米(钱不一定要用完),而米的数量是确定的,因此该题是一个多重背包问题,主要要处理的问题是米的数量与钱的问题,

米的价钱与数量的乘积大于钱数时,代表该种米是足量的,可以用多完全背包解,当小于钱数时,代表该种米时不足够的,那么我们只能用01背包选择哪袋米选还是不选,代码如下

你可能感兴趣的:(HDU)