ZOJ1711||POJ1564 DFS深搜(严格说应该是回溯)

思路很简单,给你n个数和一个sum要求从n个数中选出所有加和为sum的数值串:

肯定是先用DFS找出所有的情况然后再删掉重复的;这里我从课件里学到一种判断重复的方法,

把核心代码附上:

void findSum (int sum, int iEnd, int numSkipped) {
  if (iEnd == listlength) return;
  int newsum = sum - list[iEnd];  //取第iEnd个数
 
if ((numSkipped != list[iEnd])&&(newsum >= 0))   {
      used[iEnd] = 1;   //标记第iEnd个数已经用过
      if (newsum == 0)    {//找到一个解,输出
           numberOfSolutions++;
           for (int i = 0; i<iEnd; i++)   if (used[i])  cout << list[i] << '+';
           cout << list[iEnd] << endl;
      }
      else   findSum(newsum, iEnd+1, -1);
  }// if
 
 used[iEnd] = 0; 
  findSum(sum, iEnd+1, list[iEnd]); //不取第iEnd个数
}
 
View Code
 1 #include<cstdio>
 2 #include<cstdlib>
 3 #include<cstring>
 4 #include<iostream>
 5  
 6 using namespace std;
 7  
 8 int n,ncases,a[15],vis[15],ans;
 9 void DFS(int sum, int i,int num)
10 {
11    int j,newsum; 
12    if(i == ncases) return ;    
13    newsum = sum - a[i];  
14    //if(newsum < 0) return; 
15    if(newsum >= 0 && num!=a[i]) 
16    { 
17       vis[i] = 1;    
18       if(newsum == 0)  
19       {
20         for(j=0; j<i; j++)
21         {
22           if(vis[j]) cout<<a[j]<<'+'; 
23         }
24         cout<<a[i]<<endl;   
25         ans++; 
26       } 
27       else 
28       {
29         DFS(newsum,i+1,-1); 
30       }   
31    }  
32    vis[i] = 0;
33    DFS(sum,i+1,a[i]);       
34 }      
35 
36 int main()
37 {
38    int k;   
39    while(cin>>n>>ncases)
40    {   
41       if(n==0&&ncases==0) break; 
42       for(k=0; k<ncases; k++)
43          cin>>a[k];
44       ans = 0;   
45       memset(vis,0,sizeof(vis));                                   
46       cout<<"Sums of "<<n<<":"<<endl;                                           
47       DFS(n,0,-1); 
48       if(ans == 0)
49          cout<<"NONE"<<endl;   
50    }     
51   return 0;   
52 }     
53  

 

posted @ 2012-06-07 14:52  zhongya  阅读(184)  评论(0编辑  收藏  举报