poj1564-Sum It Up(经典DFS)
给出一个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" ); } } |