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,无解为0void 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]); //格式控制elseprintf("+%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 14为那些数和为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 != 4dfs(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*输出 4for(i=posa=1;i<6;i++)*{i=1;sum=4;posb=1b[posb]=b[1]=a[1]=3;dfs(sum+a[1],1+1,1+1)=dfs(7,2,2);(此时sum=7>4return)while(1+1=2<6但是a[1]!=a[2])-----------------------------------i=2,sum=4,posb=1b[posb]=b[1]=a[i]=a[2]=2dfs(sum+a[2],i+1,posb+1)=dfs(6,3,2)(sum=6>4return;)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]=1dfs(sum+a[4],i+1,posb+1)=dfs(5,5,2)(sum=5>4return;)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=1for(i=posa=2;i<6;i++)*{b[posb]=b[1]=a[i]=a[2]=2dfs(sum+a[i],posa=i+1,posb+1)=dfs(5,3,2)(sum=5>4return;)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=2b[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=1b[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=1b[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<4for(i=posa=6,i<6,i++))while(i+1=6 == 6))i=6,循环结束)