hdu 2844 Coins (多重背包+ 二进制优化)

题意 :

 有 n个 物品 价值 为a[i],个数为 b[i];求解 能够组成m以内的多少个数

题解 :

可以认为 到过来想 ,容量 i  被完全装满 ,按 完全装满算 即可



#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<set>
#include<map>
#define Min(a,b)  a>b?b:a
#define Max(a,b)  a>b?a:b
#define CL(a,num)  memset(a,num,sizeof(a));
#define inf 9999999
#define maxn 100005
#define eps  1e-6
#define ll long long
using namespace std;
int dp[maxn], m,n,val[200],num[200];
void complet(int cost)
{
    int i;
    for(  i = cost ; i <= m; ++i )
       dp[i] = max(dp[i],dp[i - cost] + cost);
}
void  zero(int cost)
{
    int i;
    for( i = m ;i >= cost; --i)
         dp[i] = max(dp[i],dp[i - cost] + cost);
}
void mul( int cost,int cnt )
{
    if( cost*cnt >= m)complet(cost);
    else
    {
        int  k = 1;
        while(k < cnt)
        {
            zero(cost*k);
            cnt -= k;
            k<<=1;
        }
        zero(cnt*cost);
    }
}
int main()
{
    int t,i,j;
    while(scanf("%d%d",&n,&m),n+m)
    {
        for( i = 1 ;i <= n;++i)scanf("%d",&val[i]);
        for( i =1; i <= n;++i)scanf("%d",&num[i]);

         for(i = 0; i <= m;++i)dp[i] = -inf;
         dp[0] = 1 ;

         for( i = 1;  i <= n ;++i)
         {
             mul(val[i],num[i]);
         }
         int ans  = 0;
         for( i = 1; i <= m;++i)
         {
             if(dp[i] >= 0)ans ++;
         }

         printf("%d\n",ans);
    }
}

posted @ 2012-08-10 10:18  Szz  阅读(460)  评论(0编辑  收藏  举报