搜索<1>——DFS与回溯

前言:本系列(搜索)博客主要介绍的是用DFS解决一些问题,并不是图论中的DFS

dfs相信大家都有了解,TA是一个图论中的算法。

中心思想就是:只要干不死,就往死里干!

具体来说,就是只要符合要求,就一直往前搜,知道不行了再回头搜另一种。还是看题吧。

八皇后:

一道很经典的题目。思路就是每次枚举一个皇后,然后把这个皇后占领的所有格子标记,再枚举下一个就OK了。

#include 
using namespace std;
int row[100],col[100],l[100],r[100];
int ans;
void print(){
    if(ans<=2){
        for(int k=1;k<=n;k++)
        	cout<n){
        print();
        return;
    }
    else{
        for(int i=1;i<=n;i++){
            if((!col[i]) && (!l[cnt+i]) && (!r[cnt-i+n])){
                row[cnt]=i;
                col[i]=1;
                l[cnt+i]=1;
                r[cnt-i+n]=1;
                dfs(cnt+1);
                //回溯
                col[i]=0;
                l[cnt+i]=0;
                r[cnt-i+n]=0;
            }
        }
    }
}
int main(){
    int n;    
    cin>>n;
    dfs(1);
    cout<

注意要回溯。

P2392:

为什么此题的作者不仅没被kkksc03封,还成了管理员?!?!?!?!?!?!?!?!?!?!?!?!?!

切入正题,那么由于kkksc03左右脑同时做2题(真牛),我们用一个l记录左脑,r记录右脑,枚举每道题交给哪边的脑子解决,找到两边时间较大值的最小值就结束了。

同时,虽然这题一打眼是贪心,但你会发现交上去全WA(或者几乎全WA)......

所以,老老实实DP或者DFS吧。

#include
using namespace std;
int l,r,ans,tmp;
int s[4];
int t[21][4];
void dfs(int x,int sub){
	if(x>s[sub]){
		tmp=min(tmp,max(l,r));
		return;
	}
	l+=t[x][sub];
	dfs(x+1,sub);
	l-=t[x][sub];
	r+=t[x][sub];
	dfs(x+1,sub);
	r-=t[x][sub];
}
int main(){
	for(int i=0;i<4;i++)
		cin>>s[i];
	for(int i=0;i<4;i++){
		l=r=0;
		tmp=INT_MAX;
		for(int j=0;j>t[j][i];
		dfs(0,i);
		ans+=tmp;
	}
	cout<

P2036:

思路很简单,dfs每次往后跑,如果超过n了就更新答案,要么添加,要么不添加,分别搜一下,就行了。而且,此题不需要回溯

#include 
using namespace std;
int s[15],b[15];
int n,ans=INT_MAX;
void dfs(int idx,int sour,int bitter){
    if(idx>n){
        if(sour==1 && bitter==0)
			return;
        ans=min(abs(sour-bitter),ans);
        return;
    }
    dfs(idx+1,sour*s[idx],bitter+b[idx]);
    dfs(idx+1,sour,bitter);
}
int main(){
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>s[i]>>b[i];
    dfs(1,1,0);
    cout<

咦,为什么只有70?呵,满分就是70(我也不知道为什么)。

P1036:

突然发现了这个:数据范围说1小于等于n,所以当n=1,,k

首先肯定要有一个判断素数的函数:

bool isprime(int n){
	for(int i=2;i<=n/i;i++){
		if(n%i==0)
			return false;
	}
	return true;
}

然后就是剩下的数挨个枚举选不选就行了。

void dfs(int idx,int sum,int lst){
	if(idx==k && isprime(sum)){
		ans++;
		return;
	}
	for(int i=lst;i

所以下面是完整代码:

#include 
using namespace std;
int x[10];
int n,k,ans;
bool isprime(int n){
	for(int i=2;i<=n/i;i++){
		if(n%i==0)
			return false;
	}
	return true;
}
void dfs(int cnt,int sum,int lst){
	if(cnt==k && isprime(sum)){
		ans++;
		return;
	}
	for(int i=lst;i>n>>k;
	for(int i=0;i>x[i];
	dfs(0,0,0);
	cout<

OK,以上就是本期的全部内容了。下期我会聊一聊记忆化和剪枝。ヾ( ̄▽ ̄)Bye~Bye~

温馨提示:本期的全部代码直接提交就无法AC,请不要无脑Ctrl C+Ctrl V

你可能感兴趣的:(算法,深度优先,算法)