zoj 1149 Dividing

来源:互联网 发布:js给input赋值 编辑:程序博客网 时间:2024/05/19 05:39

求可行性解的问题,多重背包解

一开始直接上多重背包一般解法,先是wa,然后TL了,后来又试了别的方法,wa,再上网搜了下看了别人的,后来改用的二进制拆分

//二进制拆分#include <bits/stdc++.h>using namespace std;#define maxn 300050int d[maxn];//存可行性解的int n[7];       //存每种物品存放了多少个int num[maxn];int cou;void add(int k,int n)  //多重背包的二进制拆分{    int i,x,tmp = 0;    for(i=0; ; i++)    {        x = 1<<i;        if( tmp + x > k )            break;        tmp += x;        num[cou++] = x*n;    }    x = k - tmp;    if( x != 0 )        num[cou++] = n*x;}int main(){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    int testnum=1;    while(scanf("%d%d%d%d%d%d",&n[1],&n[2],&n[3],&n[4],&n[5],&n[6])!=EOF){        int sum=0;        for (int i=1;i<=6;i++){            sum+=(n[i]*i);        }        if (sum==0) break;        printf("Collection #%d:\n",testnum++);        if (sum&1){            printf("Can't be divided.\n\n");            continue;        }        sum=sum/2;        cou=0;        add(n[1],1);add(n[2],2);add(n[3],3);add(n[4],4);add(n[5],5);add(n[6],6);        memset(d,0,sizeof(d));        for (int i=0;i<cou;i++){            for (int s=sum;s>=num[i];s--){                d[s]=max(d[s],d[s-num[i]]+num[i]);            }        }        int ok=0;        if (d[sum]==sum) ok=1;        if (ok) printf("Can be divided.\n\n");        else printf("Can't be divided.\n\n");    }    return 0;}


0 0
原创粉丝点击