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;
}

  

posted @ 2012-04-19 09:16  shijiwomen  阅读(541)  评论(0编辑  收藏  举报