hdu 2844 多重背包 多种硬币,每一种硬币有一点数量,看他能组成多少种钱
有两个模板 注意模板使用时的数据改变
#include <iostream> #include<cstdio> #include<cstdlib> #include<string.h> #define MAX_VOLUMN 100001 #define MAX_N 11 #define max(a,b) ((a)>(b) ? (a) : (b)) using namespace std; int vol, n; // 背包容量 ;数量 int cv[MAX_VOLUMN], num[MAX_VOLUMN], f[MAX_VOLUMN]; void ZeroOnePack(int cost, int value) //(01)体积、质量、费用;价值 { int v; for(v=vol; v>=cost; v--) f[v] = max(f[v], f[v-cost]+value); } void CompletePack(int cost, int value) //(无限)体积、质量、费用;价值 { int v; for(v=cost; v<=vol; v++) f[v] = max(f[v], f[v-cost]+value); } void MultiplePack(int cost, int value, int amount) //(多重)体积、质量、费用;价值;数量 { int k = 1; if(cost*amount >= vol) CompletePack(cost, value); else { while((amount-k) >= 0) { ZeroOnePack(cost*k, value*k); amount -= k; k = k*2; } ZeroOnePack(cost*amount, value*amount); } } void zpack( int v, int w ) { for( int i=vol; i >= w; -- i ) f[i]=max( f[i], f[i-w]+v ); } void cpack( int v, int w ) { for( int i=w; i <= vol; ++ i ) f[i]=max( f[i], f[i-w]+v ); } void dp() { int i; for(i=1; i<=n; i++) MultiplePack(cv[i], cv[i], num[i]); } int main(int argc, char **argv) { int i,k,j; while(scanf("%d %d", &n, &vol),n+vol) { memset(f, 0, sizeof(f)); for(i=1; i<=n; i++) scanf("%d",&cv[i]); for(i=1; i<=n; i++) scanf("%d",&num[i]); dp(); /* for( i=1; i <= n; ++ i ) { if( num[i]*cv[i]>=vol ) cpack( cv[i], cv[i] ); else { k=1; while( k <= num[i] ) { zpack( k*cv[i], k*cv[i] ); num[i]-=k; k <<= 1; } zpack( num[i]*cv[i], num[i]*cv[i] ); } } */ int sum=0; for( i=1; i <= vol; i++ ) { if( f[i] == i ) sum++; } printf("%d\n", sum); //最大数 } return 0; }