标签: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