码迷,mamicode.com
首页 > 其他好文 > 详细

DFS—找数字和

时间:2020-03-13 01:06:57      阅读:79      评论:0      收藏:0      [点我收藏+]

标签: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 }
View Code

 

DFS—找数字和

标签:size   +=   isp   std   als   empty   技术   --   color   

原文地址:https://www.cnblogs.com/asdfknjhu/p/12483799.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!