DFS話

DFS

最初の接触は、ツリーをトラバースデータのと深さ優先探索と幅優先探索の作品を学ぶことが、最近この問題ブラシを総括してくるので、頻繁に使用されて発見しなければなりません。古いルールは、ブログ上で良い感じにします。
DFSのブログ

おそらくルーチン

DFSを使用することが適切であるとき、DFSは、実際にあなたが戻っても、再帰的な列挙をすることができます使用され、さまざまな状況を列挙する必要があります。いくつかの場所使用していることを注意
再帰終了するとき、あること、1境界条件を
、この可変パラメータ置くために変更を加えるために使用されているものを一般的にパラメータ2.DFSを
条件3.更新、どのような状態は、さらに希望を検索
このブログエッセイテンプレートがで与えられている
ここに画像を挿入説明
一般的な、我々は検索するか否かのレコードにマークを設定する必要があり、その配列VISがあるでしょう。

簡単な例

配列の全てよりも少ない整数出力に等しい整数を入力して、実施例の全体構成を取る
、例えば、入力2、出力:12; 21

これは、同様の問題の最初の列挙ので、DFSの直接の使用です。整数関数パラメータ最初に考えたの数に応じて、上記の入力には、この問題は、それがパラメータとして入力されます。次に、終了条件は、再帰的パラメータは、整数入力と全ての出力再帰配置を終了し、この時間を超えていることです。(あなたは、コードの次の外観を理解するために待機を理解していない場合)、次に条件は整数パラメータに等しい未満で更新し、この番号が検索されていない、そうでない場合が繰り返されます。

コード

//dfs
#include<iostream>
#include<cmath>
using namespace std;

int n;
bool vis[150]={false};
int res[150]={0};

void dfs(int x){
    if(x==n+1){  //到了最后一个
        for(int i=1;i<=n;i++)
            cout<<res[i]<<" ";
        cout<<endl;
        return ;
    }

    for(int i=1;i<=n;i++){
        if(vis[i]==false){
            res[x]=i;
            vis[i]=true;
            dfs(x+1);
            vis[i]=false;
        }
    }
}

int main(){
    cin>>n;
    dfs(1);
    return 0;
}

最初からディープサーチは、すべての検索が深いのx ++、そのときのx>再帰的な時間を終了するにはn個となります。あなたはマークが背部保証を変更横断した後に戻ってそれを変更する必要があるたびに、覚えておいてください。
ここに画像を挿入説明

少し複雑

問題の今日は、共有するために使用され、ちょうどブラシにある
ここに画像を挿入説明
最初のこの二つの部分、同じ値の2つの部分に。私はあなたが同じ時間を持つことができるかどうかを確認し、ゆっくりと小さなに添加し、並べ替え、その後、偉大な一緒に入れて、この初めは貪欲で見てみたいです。しかし、出力を見て、あなたは出力の左上隅には、それは貪欲することはできません格子パーティションの最小数を含める必要があり、この時間は私がDFSを使用して、列挙するために類似しています。

考え
それは、限り、全体の部分の半分の値に等しいIなどの、二つの部分に等しいのでときに出口再帰より大きい。当然の最小格子パラメータを数えるが、それは、座標X、Yを必要とし、電流値やパラメータを記録するように、この二次元アレイを含むようにグリッドの必要性のコーナーを左上であるためです。この2次元配列の出会いの後に直接探し出すことができたときに、しかし、我々は、それはまた、検索の方向を指定する必要が分割するのは自由です、この経験を思い出すことができます

コード

#include<iostream>
#include<string.h>
#include<cmath>
using namespace std;

int n,m;//格子的高,宽,map[n][m]
int map[11][11],vis[11][11],all_sum,res=404;
int dir[4][2]={0,1,0,-1,1,0,-1,0};//搜索的四个方向

void dfs(int x,int y,int sum,int cnt){    //x,y是当前坐标,sum是搜索位置值的和,cnt记录搜索过多少格子,也就是包含左上角的那部分格子数
    if(sum>all_sum/2)//当前和超过总数和的一半
        return;
    if(sum==all_sum/2){//刚好平分时更新cnt
        res=min(res,cnt);
    }   
    for(int i=0;i<4;i++){//向四个方向搜索
        int xx=x+dir[i][0];
        int yy=y+dir[i][1];
        if(xx>=0&&xx<n&&yy>=0&&y<m&&!vis[xx][yy]){//搜索的格子在范围内且没有搜索过
            vis[xx][yy]=1;
            dfs(xx,yy,sum+map[xx][yy],cnt+1);
            vis[xx][yy]=0;
        }
    }
}

int main(){
    cin>>m>>n;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>map[i][j];
            all_sum+=map[i][j];
        }
    }

    memset(vis,0,sizeof(vis));
    vis[0][0]=1;//从左上角格子开始遍历搜索
    dfs(0,0,map[0][0],1);
    if(res==404)
        cout<<0<<endl;
    else
        cout<<res<<endl;
}

ここに画像を挿入説明
ここに画像を挿入説明

概要

ここに画像を挿入説明
実は、私は、ルーチン、またはスキルを学ぶために何かがあると思います。スキルは十分で最も時間の問題を解決するために、すぐに学習するスキルを習得。

公開された85元の記事 ウォン称賛55 ビュー20000 +

おすすめ

転載: blog.csdn.net/shelgi/article/details/104189019