POJ 1742 Coins

多重背包二进制优化,o(10*100*100000)的复杂复,2800ms卡过去的。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<queue>
#include<algorithm>
using namespace std;

struct X
{
    int val;
    int num;
}s[100+10];
int n,m;
bool flag[100000+10];
int b[20];
int y[20];

void init()
{
    b[0]=1;
    for(int i=1;i<=10;i++) b[i]=2*b[i-1];
}

int main()
{
    init();
    while(~scanf("%d%d",&n,&m))
    {
        if(n==0&&m==0) break;
        for(int i=1;i<=m;i++) flag[i]=0; flag[0]=1;
        for(int i=1;i<=n;i++) scanf("%d",&s[i].val);
        for(int i=1;i<=n;i++) scanf("%d",&s[i].num);
        for(int i=1;i<=n;i++)
        {
            int tmp=s[i].num;
            int k=0;
            while(1)
            {
                if(b[k]<tmp)
                {
                    y[k]=b[k];
                    tmp=tmp-b[k];
                }
                else
                {
                    y[k]=tmp;
                    break;
                }
                k++;
            }

            for(int h=0;h<=k;h++)
            {
                int V=s[i].val*y[h];
                for(int j=m;j>=V;j--)
                    if(flag[j-V]==1) flag[j]=1;
            }
        }
        int ans=0;
        for(int i=1;i<=m;i++) if(flag[i]==1) ans++;
        printf("%d\n",ans);
    }
    return 0;
}

 

posted @ 2016-03-24 21:15  Fighting_Heart  阅读(214)  评论(0编辑  收藏  举报