poj1014:母函数+优化

题目大意:

有1~6六种宝石,价格分别为1~6 。。给定每种宝石的个数,问能否平分给两个人

分析:

一看显然是个多重背包问题,也可以用母函数做

不过母函数的复杂度是n*v*k,第一次tle了。。

后来发现一种优化方式

当个数大于 6的时候直接把个数设为 5(奇数),6(偶数)。。

discuss 里面有位神牛给出了这个优化的证明:

http://poj.org/showmessage?message_id=342382

我把个数设成60或者61也过了。。

#include <iostream>

#include <stdio.h>

#include<string.h>

#include<algorithm>

#include<string>

#include<ctype.h>

using namespace std;

#define MAXN 10000

int a[10];

bool m[2][150000];

int main()

{

    int cas=1;

    while(scanf("%d",a+1))

    {

        int t=0;

        for(int i=2;i<=6;i++)

        {

            scanf("%d",a+i);

        }

        for(int i=1;i<=6;i++)

        {

            if(a[i]>60)

            {

                a[i]=a[i]%2?61:60;

            }

            t+=a[i]*i;

        }

        if(!t)

            break;

        printf("Collection #%d:\n",cas++);

        if(t%2)

        {

            puts("Can't be divided.");

            puts("");

            continue;

        }

        memset(m,0,sizeof(m));

        m[0][0]=1;

        for(int i=1;i<=6;i++)

        {

            for(int j=0;j<=t/2;j++)

            {

                if(m[(i-1)%2][j]==0)

                    continue;

                for(int k=0;k<=a[i];k++)

                {

                    if(k*i+j>t/2)

                        break;

                    m[i%2][k*i+j]=1;

                }

            }

        }

        if(m[0][t/2])

        {

            puts("Can be divided.");

        }

        else

        {

            puts("Can't be divided.");

        }

        puts("");

    }

    return 0;

}

 

你可能感兴趣的:(poj)