hdu 2844 多重背包的二进制优化

来源:互联网 发布:互联网数据库 编辑:程序博客网 时间:2024/05/17 07:09


多重背包解。讲多重背包拆分成完全背包和01背包,01背包部分用二进制优化。


PS:2014年1月19日00:03:06_和poj1742一样 PPS:标记数组改成bool型的。

#include<cstdio>#include<cstring>#include<cmath>#include<iostream>#include<algorithm>#include<set>#include<map>#include<queue>#include<vector>#include<string>#define eps  1e-12#define INF   0x7fffffff#define maxn 1100using namespace std;#define N 300int n,m;int a[N],c[N];int can[111111];void cal(){    for(int i=0;i<n;i++)    {        if(a[i]*c[i]>=m)        {            for(int v=a[i];v<=m;v++)                can[v]|=can[v-a[i]];        }        else        {            int k=1;            int amount=c[i];            while(k<amount)            {                int tmp=k*a[i];                for(int v=m;v>=tmp;v--)                     can[v]|=can[v-tmp];                amount-=k;                k<<=1;            }            if(amount)            for(int v=m;v>=amount*a[i];v--)                can[v]|=can[v-a[i]*amount];        }    }}int main(){    while(scanf("%d%d",&n,&m)&&(n|m))    {        for(int i=0;i<n;i++) scanf("%d",&a[i]);        for(int i=0;i<n;i++) scanf("%d",&c[i]);        if(m<0) {printf("0\n");continue;}   //一直纳闷为什么不能用下面的初始化,原来是m可能为负数,真坑。        memset(can,0,sizeof(int)*(m+10));        // memset(can,0,sizeof(can));           int ans=0;can[0]=1;        cal();        for(int i=1;i<=m;i++) if(can[i]) ans++;        printf("%d\n",ans);    }    return 0;}


4 0
原创粉丝点击