2020.10.31-笔记-深度优先与宽度优先

深度优先搜索(DFS)

从某个状态开始,不断转移状态,直到无法转移,然后退回前一步状态,继续转移到其他状态,直到找到最终的解。深度优先搜索采用递归函数实现比较简单。
2020.10.31-笔记-深度优先与宽度优先_第1张图片

给定整数a[1],a[2],…,a[n],判断是否可以从中选出若干数,使它们和为k。

限制条件:

  • 1<=n<=20
  • -108<=a[i]<=108
  • -108<=k<=108

输入

n=4
a={1,2,4,7}
k=13

输出

yes

从a[1]开始按顺序每项选择加或不加,全部n项决定完后判断和是否为k。

程序复杂度分析 2n+1 => O(2n)

#include 

int a[20];
int n, k;

bool dfs(int i, int sum) {
   
	if (i == n) return sum == k;        		//全部n项决定完后判断和是否为k。
	if (dfs(i + 1, sum)) return true;			//选择不加a[i]
	if (dfs(i + 1, sum + a[i])) return true;	//选择加a[i]
	return false;								//无论是否加a[i]都不等于k,返回false
}

void solve() {
   
	if (dfs(0, 0)) printf("yes\n");				//从第一项开始调用dfs
	else printf("No\n");				
}

int main()
{
   
	scanf_s("%d", &n);							//输入
	for (int i = 0; i < n; i++) {
   
		scanf_s("%d", &a[i]);
	}
	scanf_s("%d", &k);
	
	solve();
}

深度优先搜索从最初状态出发,遍历所有可以达到的状态,由此可以堆所有状态进行操作,或列举出所有状态

有一个N*M的园子,雨后积水。八连通的积水视为连在一起,为一个水坑。求园里总共有多少水坑。
+++
+w+
+++
加号是相对w的八连通方向

限制条件

  • N,M<=100

输入

N=10,M=12
园子如下图(‘W’表示积水,’.’表示没有积水)
W . . . . . . . . WW .
. WWW . . . . . WWW
. . . . WW . . . WW .
. . . . . . . . . WW .
. . W . . . . . . W . .
. W . W . . . . . WW .
W. W . W . . . . . W .
. W . W . . . . . . W .
. . W . . . . . . . W .
(程序中输入按行输入,之间不带空格)

输出

3

从任意W开始,不停地将相邻W用’.‘代替,一次DFS后与这个W相连接的全部W被替换为’.’。当地图中全部W被替换,DFS次数就是水坑数。

程序复杂度分析 O(8 * N * M)=O(N * M)

#include
#pragma warning(disable : 4996)

int N, M;
char field[100]

你可能感兴趣的:(经典算法,算法,c++,队列,深度搜索)