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 }

浙公网安备 33010602011771号