给出一个n,k,再给出的n个数中,输出所有的可能使几个数的和等于k

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

明显的DFS,这个dfs方程让我纠结啊,递归的我头都大了,但是看下答案稍微来点灵感了,在这里dfs函数方程要有哪些参数?

首先要从当前数往后开始dfs,所以要有个参数是当前搜索的数组下标

其次,要判断和=t,所以还要有个保存当前的和的参数,在这里我用t减去当前和,所以当此参数等于0那么就是找到满足条件

最后要输出此序列,所以还要有个参数来标记当前要找的数在数组里的位置

找到三个参数后就好办多了,看代码吧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int n,t;
int num[101];
int r[101];
bool flag;
void dfs(int len,int k,int last)
{
    int result;
    if(last==0)
    {
        flag=false;
        for(int i=0;i<len;i++)
        if(i==0)printf("%d",r[i]);
        else printf("+%d",r[i]);
        printf("\n");
        return ;
    }
    for(int i=k;i<n;i++)
     {
          
         if(i==k||num[i]!=num[i-1]&&last-num[i]>=0)// 去除重复的操作
         {
         r[len]=num[i];
         dfs(len+1,i+1,last-num[i]);
         }      
     }
}
int main()
{
    while(scanf("%d%d",&t,&n)!=EOF)
    {
        if(t==n&&n==0)break;
        flag=true;
        for(int i=0;i<n;i++)
        scanf("%d",&num[i]);
        printf("Sums of %d:\n", t);
        dfs(0,0,t);
        if(flag)printf("NONE\n");
    }
     
}