标签:size += isp std als empty 技术 -- color
题目: 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\n"); 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\n"); 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\n"); while (!s.empty()) { printf("%d ", s.top()); s.pop(); }puts(""); } else printf("NO\n"); } 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\n"); 36 for (i = 1, flag = 0; i <= n; i++) 37 if (state[i]) 38 printf("%d ", a[i]); 39 printf("\n"); 40 } 41 else 42 printf("NO\n"); 43 } 44 return 0; 45 }
标签:size += isp std als empty 技术 -- color
原文地址:https://www.cnblogs.com/asdfknjhu/p/12483799.html