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