DFS—找数字和
Posted asdfknjhu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了DFS—找数字和相关的知识,希望对你有一定的参考价值。
题目: http://www.fjutacm.com/Contest.jsp?cid=860#P3
代码
一,
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<queue> #include<string.h> using namespace std; int map[30], vis[30], way[30]; int n, k; queue<int>q; int flag = 0, sum = 0; void DFS(int j,int res) { if (flag == 1) return; if (sum > k) return; if (sum == k) { flag = 1; printf("YES "); for (int i = 0; i < res ; i++) printf("%d ", way[i]); puts(""); return; } for (int i = 0; i < n; i++) { if (vis[i] == 0) { vis[i] = 1; way[res] = map[i]; sum += map[i]; DFS(i + 1, res + 1); vis[i] = 0; sum -= map[i]; } } } int main(void) { while (scanf("%d%d", &n, &k) != EOF) { for (int i = 0; i < n; i++) { scanf("%d", &map[i]); } DFS(0, 0); if (flag == 0) printf("NO "); memset(way, 0, sizeof(way)); memset(vis, 0, sizeof(vis)); flag = 0, sum = 0; } }
① 这种需要记录路径的,好像只能利用递归的回溯来记录,
如果是使用栈的话,因为要同时压好几个数进栈,如果直接记录的画,就把同级的结点给记录上了,这样就错了,
但如果是递归的话,因为不用压栈,他直接回溯回来使用数据,自然不用把数据压入栈中。
现在我也不知道有没有办法可以解决这个问题,就只能用递归。
② 注意回溯时,要把改变的条件改回来。
像这一段,
i 是函数传参时直接改变,回溯时就自己变回来了,不用改变
而数组 vis 和 数字 sum 不是 参数,无论你函数调用多少次,他还是不会变,所以,必须在它回溯时给减回来
if (vis[i] == 0)
{
vis[i] = 1;
way[res] = map[i];
sum += map[i];
DFS(i + 1, res + 1);
vis[i] = 0;
sum -= map[i];
}
二,
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #include<stack> using namespace std; stack<int>s; int n, k, a[30]; bool DFS(int i, int sum) { if (sum > k) return false; if (i == n) return k == sum; if (DFS(i + 1, sum + a[i])) //选 a[i] { s.push(a[i]); return true; } if (DFS(i + 1, sum)) //不选 a[i] return true; return false; } int main(void) { while (scanf("%d%d", &n, &k) != EOF) { for (int i = 0; i < n; i++) { scanf("%d", &a[i]); } if (DFS(0, 0)) { printf("YES "); while (!s.empty()) { printf("%d ", s.top()); s.pop(); }puts(""); } else printf("NO "); } return 0; }
① 就是看到这个递归式才想起来这题的判断可以用 dp 做,不过储存路径还得是 DFS 才可以
三,
1 #define _CRT_SECURE_NO_WARNINGS 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<string.h> 5 bool state[25]; 6 int a[25], k; 7 int dfs(int sum, int n) 8 { 9 if (sum == k) // 找到了,开始回溯 10 return 1; 11 if (n == 0) // 找完了,开始回溯 12 return 0; 13 14 while (n) 15 { 16 if (dfs(sum + a[n], n - 1)) // 如果是找到了结果的回溯,才记录 17 { 18 state[n] = 1; 19 return 1; 20 } 21 n--; 22 } 23 24 } 25 int main(void) 26 { 27 int i, flag, n; 28 while (scanf("%d%d", &n, &k) != EOF) 29 { 30 memset(state, 0, 25); 31 for (i = 1; i <= n; i++) 32 scanf("%d", &a[i]); 33 if (dfs(0, n)) 34 { 35 printf("YES "); 36 for (i = 1, flag = 0; i <= n; i++) 37 if (state[i]) 38 printf("%d ", a[i]); 39 printf(" "); 40 } 41 else 42 printf("NO "); 43 } 44 return 0; 45 }
以上是关于DFS—找数字和的主要内容,如果未能解决你的问题,请参考以下文章