poj 1276 cash machine (多重背包)

有一个Cash Machine,里面装有t种面值为n[i]的货币,每种有v[i]张。问在所换金额不超过cash元钱的情况下,所能换取的最大金额。

 

多重背包,转换成01背包来做,其中要用到二进制优化。《背包九讲》上讲的挺不错,在每件物品价值前加上系数,并保证这些系数的组合包括1..n的所有数且总和为n。

代码:

#include<cstdio>
#include<cstring>
#define Max(a, b)   a>b?a:b
int dp[ 100005] ;
int val[ 105] ;
int main(){
     int cash, n, v, g, i, j, count ;
     while(~scanf( " %d%d ", &cash, &n)){
         if(!cash||!n){
             while(n--)
                scanf( " %d%d ", &g, &v) ;
            printf( " 0\n ") ;
             continue ;
        }
        count =  0 ;
        memset(dp,  0sizeof(dp)) ;
         while(n--){
            scanf( " %d%d ", &g, &v) ;
             // 二进制优化
            i =  1 ;
             while(g>=i){
                val[count++] = i * v ;
                g -= i ;
                i *=  2 ;
            }
             if(g)   val[count++] = v * g ;
        }
         // 01背包求解
         for(i= 0; i<count; i++){
             for(j=cash; j>=val[i]; j--){
                dp[j] = Max(dp[j], dp[j-val[i]]+val[i]) ;
            }
        }
        printf( " %d\n ", dp[cash]) ;
    }
     return  0 ;

} 

你可能感兴趣的:(mac)