离散化+深搜。

对给出的n个数排序,然后离散,求出每个数有多少个,然后递归判断每个数出现多少次时 能使和等于sum,需要注从大数开始深搜。。

代码:

# include<stdio.h>
# include<string.h>
# include<stdlib.h>
int a[20],b[20],c[20],sum,ans,flag,ys;
int
cmp(const void *a,const void *b)
{

    return
*(int *)b - *(int *)a;
}

void
dfs(int i)
{

    int
j,k,h;
    for
(j=b[i];j>=0;j--)
    {

        ans+=a[i]*j;
        c[i]=j;
        if
(ans>sum)
        {

            ans-=a[i]*j;
            continue
;
        }

            if
(ans==sum)
            {

                flag=0;
                for
(k=1;k<=i;k++)
                {

                    for
(h=1;h<=c[k];h++)
                    {

                        if
(flag==0) {printf("%d",a[k]);flag=1;}
                        else
printf("+%d",a[k]);
                    }
                }

                printf("\n");
                ans-=a[i]*j;
                continue
;
            }

            if
(i==ys) {ans-=a[i]*j;return;}
        dfs(i+1);
        ans-=a[i]*j;
    }
}

int
main()
{

    int
i,n;
    while
(scanf("%d%d",&sum,&n)!=EOF)
    {

        if
(sum==0 && n==0) break;
        for
(i=1;i<=n;i++)
            scanf("%d",&a[i]);
        qsort(a+1,n,sizeof(a[1]),cmp);
        memset(b,0,sizeof(b));
        ys=1;
        b[ys]=1;
        for
(i=2;i<=n;i++)
        {

            if
(a[i]==a[i-1]) b[ys]++;
            else

            {

                ys++;
                a[ys]=a[i];
                b[ys]=1;
            }
        }

        ans=0;
        flag=0;
        printf("Sums of %d:\n",sum);
        dfs(1);
        if
(flag==0) printf("NONE\n");
    }

    return
0;
}

posted on 2011-05-16 18:28  奋斗青春  阅读(438)  评论(0编辑  收藏  举报