hdu1557

/*
分析:
    这题做的我好郁闷……,一开始的思路、方法就是对的,结果数组
开小了,吃了个WA。也不是没有想到数组是不是开小了,但想到以前数
组开小的话,就会给个数组越界,而不是WA,也就放弃这个想法了……
结果硬生生调试了仨小时,最后的结论还是:数组越界………………


    刚开始找错的时候,还以为有权值是0的因素呢。硬生生的改编出了
权值含0的版本的母函数,算是因祸得福吧- -I。


    用母函数的这个题的注意点儿:要进行n次母函数而不是一次,for
(z=1;z<=n;z++),让下标为z的数先不参与母函数。说到这儿应该懂了吧。


                                                            2012-06-27
*/










#include"stdio.h"
#include"string.h"
int main()
{
    int T;
    int n;
    int num[22];
    int limit;
    int a,b,aim;
    int c1[100001],c2[100001];
    int ans[22];
    int z,i,j,k;
    int d;


    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        limit=0;
        for(i=1;i<=n;i++)    {scanf("%d",&num[i]);limit+=num[i];}
        aim=limit/2;
        aim++;




        if(n==1)    {printf("1\n");continue;}


        for(z=1;z<=n;z++)
        {
			for(j=0;j<=limit;j++)	c1[j]=c2[j]=0;
            c1[0]=1;
            if(z==1)    {c1[num[2]]=1;d=2;}
            else        {c1[num[1]]=1;d=1;}


            for(i=1;i<=n;i++)
            {
                if(i==d)    continue;
                if(i==z)    continue;
                for(j=0;j<=limit;j++)
                {
                    if(c1[j]==0)    continue;
                    for(k=0;k<2;k++)c2[k*num[i]+j]+=c1[j];
                }
                for(j=0;j<=limit;j++)
                {
                    c1[j]=c2[j];
                    c2[j]=0;
                }
            }


            a=aim-num[z];
            if(a<0)    a=0;
            b=aim-1;
            ans[z]=0;
            for(j=a;j<=b;j++)    ans[z]+=c1[j];
        }


        for(i=1;i<n;i++)    printf("%d ",ans[i]);
        printf("%d\n",ans[i]);
    }
    return 0;
}


你可能感兴趣的:(hdu1557)