HDU 1258 Sum It Up 深搜

http://acm.hdu.edu.cn/showproblem.php?pid=1258

题意:

  第一个数为sum,第二数N为后面有长度为N的序列(后一项小于等于前一项),要在这个序列中找出一组数加起来

等于sum。

 

坑爹:

  要输出所有的情况,但不能重复。

 

解法:

  用DFS的时候每次按顺序在num数组中找到一个值然后判断有没超过sum,没有的话就把它记录在save数组中,

然后再用review记录当前num[ i ] 的值,这样的话在DFS完成之后再找下一个值进行试探的时候就要判断是否与

review的值相同,相同的话就不用再进行DFS了(序列是严格的后一项小于等于前一项,所有review的值一旦改变了

就不会出现之前出现过的值了)。

 

View Code
 1 #include<iostream>
 2 using namespace std;
 3 
 4 const int maxn = 12 + 10;
 5 const int INF = 0x3fffffff;
 6 int num[maxn];
 7 int save[maxn];
 8 int T;
 9 int n;
10 int mark;
11 
12 void DFS(int sum,int num_mark,int save_mark)
13 {
14     if(sum == T)                       //找到一组解
15     {
16         mark = 1;
17         int i;
18         for(i=1; i<save_mark; i++)
19         {
20             cout<<save[i];
21             if(i != save_mark - 1)
22             {
23                 cout<<"+";
24             }
25             else
26             {
27                 cout<<endl;
28             }
29         }
30         return ;
31     }
32     if(sum > T)
33     {
34         return ;
35     }
36 
37     int i;
38     int review = INF;
39     for(i=num_mark; i<=n; i++)
40     {
41         if(sum + num[i] <= T && review != num[i])       
42         {
43             sum = num[i] + sum;
44             save[save_mark] = num[i];
45             review=num[i];
46             DFS(sum,i+1,save_mark+1);  //因为序列是递减的,就算找不到review也不用还原,review更新过了就不会在遇到之前的值了.
47             sum = sum - num[i];
48         }
49     }
50     
51 }
52 
53 int main()
54 {
55     while(cin>>T>>n,n&&T)
56     {
57         int i;
58 
59         for(i=1; i<=n; i++)
60         {
61             cin>>num[i];
62         }
63         mark = 0;
64         cout<<"Sums of "<<T<<":"<<endl;
65         DFS(0,1,1);
66         if(!mark)
67         {
68             cout<<"NONE"<<endl;
69         }
70     }
71     return 0;
72 }

 

 

posted @ 2012-09-11 13:20  pc....  阅读(165)  评论(0)    收藏  举报