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背包选择哪袋米选还是不选,代码如下

posted @ 2011-08-05 22:26  wutaoKeen  阅读(729)  评论(0编辑  收藏  举报