HDU 2844 Coins 多重背包
该题是母函数的变种,也是一种多重背包问题,由于写了几篇这样的,所以就不重累述了,如果不懂可以看一下背包九讲;
#include<stdio.h> #include<stdlib.h> int CompletePack( int f[],int val,int money ,int sum)//完全背包 { for( int i=val; i<=money;i++ ) { if( i>=val&&f[ i-val ]+val>f[i] ) { f[i]=f[i-val]+val; if( f[ i ]==i )//如果相等,则代表有这种情况 { sum++; } } } return sum; } int ZeroOnePack( int f[],int n,int val,int money,int sum )//01背包 { int t=n*val; for( int i=money; i>=t; i-- ) if( i>=t&& f[ i-t ]+t>f[i]) { f[ i ] = f[i-t] +t; if( f[i]==i )//如果相等,则代表有这种情况 { sum++; } } return sum; } int DP( int val[],int num[], int n, int money ) { int f[100024]={0},sum=0; for( int i=1; i<=n; i++ ) { if( num[i]*val[i]>=money ) sum=CompletePack( f,val[i],money,sum ); else { int k=1,count=num[i]; while( k<count ) { sum=ZeroOnePack( f,k,val[i] ,money,sum); count=count-k; k=k<<1; } sum=ZeroOnePack( f,count,val[i] ,money,sum); } } return sum; } int main() { int n,money,val[124],num[124]; while( scanf( "%d%d",&n,&money ),n||money ) { for( int i=1; i<=n; i++ ) scanf( "%d",&val[i] ); for( int i=1; i<=n; i++ ) scanf( "%d",&num[ i ] ); printf( "%d\n",DP( val, num, n,money ) ); } return 0; }