HDU:Sum It Up

Sum It Up

Problem Description
Given a specified total t and a list of n integers, find all distinct sums using numbers from the list that add up to t. For example, if t=4, n=6, and the list is [4,3,2,2,1,1], then there are four different sums that equal 4: 4,3+1,2+2, and 2+1+1.(A number can be used within a sum as many times as it appears in the list, and a single number counts as a sum.) Your job is to solve this problem in general.
 
Input
The input will contain one or more test cases, one per line. Each test case contains t, the total, followed by n, the number of integers in the list, followed by n integers x1,...,xn. If n=0 it signals the end of the input; otherwise, t will be a positive integer less than 1000, n will be an integer between 1 and 12(inclusive), and x1,...,xn will be positive integers less than 100. All numbers will be separated by exactly one space. The numbers in each list appear in nonincreasing order, and there may be repetitions.
 
Output
For each test case, first output a line containing 'Sums of', the total, and a colon. Then output each sum, one per line; if there are no sums, output the line 'NONE'. The numbers within each sum must appear in nonincreasing order. A number may be repeated in the sum as many times as it was repeated in the original list. The sums themselves must be sorted in decreasing order based on the numbers appearing in the sum. In other words, the sums must be sorted by their first number; sums with the same first number must be sorted by their second number; sums with the same first two numbers must be sorted by their third number; and so on. Within each test case, all sums must be distince; the same sum connot appear twice.

Sample Input
  
  
4 6 4 3 2 2 1 1 5 3 2 1 1 400 12 50 50 50 50 50 50 25 25 25 25 25 25 0 0
Sample Output
  
  
Sums of 4: 4 3+1 2+2 2+1+1 Sums of 5: NONE Sums of 400: 50+50+50+50+50+50+25+25+25+25 50+50+50+50+50+25+25+25+25+25+25

题目意思:求那些数的和为所给的t值,并按照从大小的层次进行输出。

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int a[1005],b[1005],n,t,state;//a用于存放输入的一串数,b用来存放要输出的数。n为输入整数的个数,t代表要求的和,state代表是否有解,有解为1,无解为0
void dfs(int sum,int posa,int posb)//sum为当前和值,posa为到a中的第几个数了,posb代表b数组有几个数
{
    int i;
    if(sum > t)//如果当前和值大于要求的值,return返回到递归的上一层
        return;
    if(sum == t)//如果相等
    {
        state=1;//代表有解
        for(i = 0;i < posb; i++)//输出b数组中的数
        {
            if(i == 0)
                printf("%d",b[i]); //格式控制
            else
                printf("+%d",b[i]);
        }
        printf("\n");
    }
    for(i = posa;i < n; i++)
    {
        b[posb]=a[i];
        dfs(sum+a[i],i+1,posb+1);
        while(i+1 < n && a[i] == a[i+1])  //如果执行这一步说明sum+第i个数大于t,如果第i个数与
     // 第i+1个数相等,那么sum加上第i+1个数必定比t大,不必在考虑第i+1个数了
            i++;
    }
}
bool cmp(int a,int b)  //让数组a从大到小排序
{
    return a>b;
}
int main()
{
    int i;
    while(~scanf("%d%d",&t,&n))
    {
        if(t == 0 && n == 0)
            break;
        state=0;
        for(i=0;i<n;i++)
            scanf("%d",&a[i]);
        sort(a,a+n,cmp);
        printf("Sums of %d:\n",t);
        dfs(0,0,0);
        if(state==0)
        printf("NONE\n");
    }
    return 0;
}

对第一组测试数据的模拟:
4 6 4 3 2 2 1 1
4为那些数和为4,6为提供6个整数。
a[0]=4    a[1]=3   a[2]=2   a[3]=2    a[4]=1   a[5]=1
最开始sum=0,posa=0,posb=0
开始sum=0<4 而且 sum != 4
dfs(0,0,0) 
(
    for(i=posa=0;i<6;i++)
    {
        sum=0,i=0;posb=0;
        b[posb]=b[0]=a[0]=4;
        dfs(sum+a[0],i+1,posb+1)=(0+4,0+1,0+1)=(4,1,1)
        (
        此时sum==4,
        state=1;
        for(i=0;i<posb;i++)   //posb=1
        *输出 4
        for(i=posa=1;i<6;i++)
        *{
            i=1;sum=4;posb=1
            b[posb]=b[1]=a[1]=3;
                    dfs(sum+a[1],1+1,1+1)=dfs(7,2,2);
                    (
            此时sum=7>4
            return
            )
                while(1+1=2<6但是a[1]!=a[2])
            -----------------------------------
           i=2,sum=4,posb=1
           b[posb]=b[1]=a[i]=a[2]=2
                   dfs(sum+a[2],i+1,posb+1)=dfs(6,3,2)
           (
            sum=6>4
            return;
           )
           while(i+1=2+1<3&&a[2]=2 == a[3]=2)
            i++=2+1=3;
           ----------------------------------------
                   i=4,sum=4,posb=1;
                   b[posb]=b[1]=a[4]=1
                   dfs(sum+a[4],i+1,posb+1)=dfs(5,5,2)
                   (
            sum=5>4
            return;
           )
                   while(i+1=4+1=5<6,a[4]==a[5])
                         i++=5
           --------------------------------------------
           i=6
           跳出循环
        }*
        i=1,sum=0,posb=0;
        (
            b[posb]=b[0]=a[i]=a[1]=3;
            dfs(sum+a[i],posa=i+1,posb+1)=dfs(3,2,1)
            (
                现在sum=3,posa=2,posb=1
                for(i=posa=2;i<6;i++)
                *{
                    b[posb]=b[1]=a[i]=a[2]=2
                    dfs(sum+a[i],posa=i+1,posb+1)=dfs(5,3,2)
                    (
                    sum=5>4
                    return;
                    )
                    while(i+1=2+1=3<6,a[2]==a[3]=2)
                     i++=3;
                           --------------------------------
                    i=4,sum=3,posa=2,posb=1;
                                b[posb]=b[1]=a[i]=a[4]=1;
                    dfs(sum+a[i],posa=i+1=5;posb+1)=dfs(4,5,2)
                                (
                     sum=4=t;
                                     for(i=0;i<2;i++)
                          *输出3+1;
                     for(i=posa=5;i<6;i++)
                     *{
                         i=5,sum=4,posa=5,posb=2
                         b[posb]=b[2]=a[i]=a[5]=1;
                             dfs(sum+a[i],posa=i+1,posb+1)=dfs(5,6,3)
                         (
                         sum=5>4;
                         return;
                          ) 
                          while(i+1=6不小于6)
                 ------------------------------------------
                    i=6不小于6循环结束
                     }*
                   )
                   while(i=4+1=5<6,但是a[4]=a[5]=1)
                   i++=5
                              ------------------------------------------------
                  i=6,不小于6,循环结束
                }*
                    while(i+1=1+1=2<6 , a[1]!=a[2])
             )
         i=2,sum=0,posa=0,posb=0;
               (
            b[posb]=b[0]=a[i]=a[2]=2;
            dfs(sum+a[i],posa=i+1,posb+1)=dfs(2,3,1)
            for(i=posa=3;i<6;i++)
            *{
                b[posb]=b[1]=a[i]=a[3]=2;
                dfs(sum+a[i],posa=i+1,posb+1)=dfs(4,4,2)
                (
                    sum=4=t;
                    输出 2,2
                )
                while(i+1=4<6,a[4]!=a[5])
                ---------------------------------------------
                i=4;sum=4,posa=4,posb=1
                b[posb]=b[2]=a[i]=a[4]=1;
                dfs(sum+a[i],posa=i+1,posb+1)=dfs(5,5,2)
                ( 
                    sum=5>4;
                    return;
                }
                while(i+1=5<6,a[4]==a[5])
                i++=5;
                -----------------------------------------------
                  i=6;
               }*
         )
         i=3,sum=0,posa=0,posb=0;
         (
            b[posb]=b[0]=a[i]=a[3]=2;
            dfs(sum+a[i],posa=i+1,posb+1)=dfs(2,4,1)
            sum=2<4;
            for(i=posa=4;i<6;i++)
            *{
            b[posb]=b[1]=a[i]=a[4]=1;
            dfs(sum+a[i],posa=i+1,posb+1)=dfs(3,5,2)
            {
                sum=3<4;
                for(i=posa=5;i<6;i++)
                *{
                b[posb]=b[2]=a[i]=a[5]=1;
                dfs(sum+a[i],posa=i+1,posb+1)=dfs(4,6,3)
                (
                    sum=4=t;
                    *输出2,1,1;
                    for(i=posa=6;i<6;i++)
                    while(i+1=6+1=7>6)
                )
                while(i+1=6 == 6不小于6)
                                ------------------------
                i++=6,for循环结束
                *}    
            i=5,posa=4,sum=2,posb=1
                b[posb]=b[1]=a[i]=a[5]=1;
            dfs(sum+a[i],posa=i+1,posb+1)=dfs(3,6,2)
                        (
                sum=3<4;
                for(i=posa=6;i<6;i++)
            )
            i=6;
             }*
        )
        i=4,sum=0;posa=0,posb=0;
        (
            b[posb]=b[0]=a[i]=a[4]=1;
            dfs(sum+a[i],posa=i+1,posb+1)=dfs(1,5,1)
            (
                sum=1<4;
                for(i=posa=5;i<6;i++)
                b[posb]=b[1]=a[i]=a[5]=1;
                dfs(sum+a[i],posa=i+1,posb+1)=dfs(2,6,2)
                (
                    sum=2<4;
                    for(i=posa=6;i<6;i++)
                )
        )
        i=5,sum=0,posa=0,posb=0;
        (
            b[posb]=b[0]=a[i]=a[5]=1;
            dfs(sum+a[i],posa=i+1,posb+1)=dfs(1,6,1)
            (
                sum=1<4
                for(i=posa=6,i<6,i++)
            )
            while(i+1=6 == 6)
        )
        i=6,循环结束
)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值