1. 激しい疲労の DFS と BFS を理解する
徹底的な暴力
ブルート フォースによる枯渇は、問題を解決する際に最も一般的に使用される方法であり、dfs および bfs アルゴリズムは、この方法の 2 つの非常に重要なツールです。
実は最も単純な網羅的手法は級数の総和などの直接走査であり、配列を走査することで問題の答えが得られるのですが、これは先ほど説明した動的計画法アルゴリズムの実行方法と同じです前回の2つのブログの特徴 「分解できる、1回で解決できる、保存できる」の3つがあると言いましたが、分解とは、どんなに複雑なデータでも同じように解決できることが前提です。一度に解かれ, 各部分問題の解を表す. 答えは現在の最適解であり, これは大域的最適解の部分解でもある. これは no aftereffect と呼ばれる. 実際, no aftereffect は実際には局所 的 な決定はグローバルな決定とは何の関係もありませんが, 正確に言えば, それはローカルな決定の最適解です. 解決策の外にある決定は決してグローバルな決定のサブ決定にはなりません . 最後に, サブ質問への答えができる場合保存されている場合、直接トラバーサルまたは動的プログラミングを実行して、必要な答えを得ることができます。
dfs と bfs の特徴
序文で直接トラバーサルという網羅的な手法について触れましたが、動的計画法もその一つで、「分解可能、1回限りの解、保存」という特徴を持っており、dfsとbfsの唯一の違いは「1つではない」ということです。 -時間解」。つまり、最適解は存在せず、部分問題の各決定は大域解の部分解である可能性があり、これは余効を持つと呼ばれますが、正確には、局所決定はグローバル決定のサブ決定、この種の問題を解決する方法、dfsおよびbfsアルゴリズムは、この種の問題の天敵です。
2. dfs と bfs の方法をマスターして問題を解決する
1. dfs は、「バックトラック」機能によって後遺症を解決します。
例
分析する
問題は、与えられた n*n のチェス盤において、チェスの駒の位置が互いに衝突しないという条件の下で、チェス盤の領域に配置されたチェスの駒の数が k であるスキームの数は何ですか? 1 . 手前のチェスの駒を先に置き、次に
置くことができます 以下のチェスの駒 (分解可能)
2. ボードの位置ごとに、置くか置かないかの 2 つの決定があり、各チェスの駒の 2 つの決定が意味を満たす場合があります。 3. 前から後ろへの意思
決定プロセス中に、配置されたチェスの駒の数を記録できます (保存できます)。
コード
#include<iostream>
#include<cstdio>
using namespace std;
const int N = 100;
bool col[N],row[N];
char g[N][N];
int cnt = 0,n,m;
void dfs(int x,int y,int k)
{
if(x == n) return;
if(k == m)
{
cnt++;
return;
}
if(y == n)
{
y = 0;
x++;
}
dfs(x,y+1,k);//先递归遍历左子树,即不放皇后的操作
if(!col[y]&&!row[x]&&(g[x][y] == '#'))
{
col[y] = row[x] = true;
dfs(x,y+1,k+1);//再递归遍历右子树
col[y] = row[x] = false;
}
}
int main()
{
while(1)
{
scanf("%d%d",&n,&m);
if(n == -1&&m == -1) break;
for(int i = 0;i<n;i++)
for(int j = 0;j<n;j++)
cin>>g[i][j];
dfs(0,0,0);
printf("%d\n",cnt);
cnt = 0;
}
return 0;
}
2. bfs は「待ち行列」機能によって後遺症を解決します。
例
分析する
問題は、与えられた L*R*C 迷路で、「S」から「E」まで歩くのに何分かかるかということです 1. 一歩一歩歩くことができます (分解可能
)
2. 各ステップには、上、下、左、右、前、後ろ、意思決定の各ステップは、質問の意味を満たすことができます(ポストエフェクト付き) 3.前から後ろへの意思決定の過程で、
いくつ分が使用されました(保存できます)
コード
#define _CRT_SECURE_NO_WARNINGS
//#define LOCAL
#include <iostream>
#include <cstring>
#include <queue>
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
const int N=35;
int L,R,C;
int sx,sy,sz,ex,ey,ez;
bool flag;
char g[N][N][N];
bool st[N][N][N];
int dist[N][N][N];
struct Node
{
int z,x,y;
};
int dx[]={1,-1,0,0,0,0};
int dy[]={0,0,1,-1,0,0};
int dz[]={0,0,0,0,1,-1};
void bfs(int sz,int sx,int sy)
{
memset(dist,0x3f,sizeof dist);
Node input;
input.z=sz,input.x=sx,input.y=sy;
queue<Node>q;
q.push(input);
st[sz][sx][sy]=1;
dist[sz][sx][sy]=0;
while(q.size())
{
Node t=q.front();
if(t.z==ez&&t.x==ex&&t.y==ey)
{
flag=1;
break;
}
q.pop();
for(int i=0;i<6;i++)
{
int a=t.z+dz[i];
int b=t.x+dx[i];
int c=t.y+dy[i];
if(a<0||b<0||c<0||a>=L||b>=R||c>=C)continue;
if(st[a][b][c]||g[a][b][c]=='#')continue;
st[a][b][c]=1;
Node tmp;
tmp.z=a,tmp.x=b,tmp.y=c;
q.push(tmp);
dist[a][b][c]=dist[t.z][t.x][t.y]+1;
}
}
}
void solve()
{
while(~scanf("%d%d%d",&L,&R,&C)&&(L||R||C))
{
for(int i=0;i<L;i++)
for(int j=0;j<R;j++)
scanf("%s",g[i][j]);
for(int i=0;i<L;i++)
for(int j=0;j<R;j++)
for(int k=0;k<C;k++)
{
if(g[i][j][k]=='S')sz=i,sx=j,sy=k;
if(g[i][j][k]=='E')ez=i,ex=j,ey=k;
}
memset(st,0,sizeof st);
flag=0;
bfs(sz,sx,sy);
if(flag) printf("Escaped in %d minute(s).\n",dist[ez][ex][ey]);
else puts("Trapped!");
}
return;
}
int main()
{
#ifdef LOCAL
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif
int t = 1;//cin>>t;
while(t--){
solve();
}
return 0;
}
〜ご覧いただきありがとうございます❥(^_-)