简单dfs专题

由于被状压DP打自闭,觉着来dfs找找自信,没成想依旧自闭orz

HDU 2610 Sequence one

题意:

给出n个数字,让你求出非递减序列,且个数<p ( find the first P subsequences 前p个,当时怎么就没get呢)。序列的顺序是和下标有关的,也就是说按下标排序,不能出现重复。

思路:

dfs(last , now , len ),main函数遍历序列长度len。

dfs思想就是深搜搜到底(当前长度now = len),然后输出,接着回溯查找下一个。这样是满足题目要求的按下标排序,下标小的在前。开个数组s[ ]保存一路过来的结果。 难点在于剪枝,这里有三种剪枝

1) 当找到的序列个数 cnt == p , 结束递归

2)例如 1 2 3 3 4 3 , 我们希望找长度为2的序列,当我们找到第一位上的值 3 即序列为 3 X ,  X的可选值有 3 4 3,那么最后一个3 和第一个3 是一种情况,我们要剪掉 即查找 [last+1 --- j-1] 上有没有和 a[j]相等的 , a[j] 就是最后一个3

3)假如扫了一遍过去,cnt的值没有变化,那么证明这个序列已经不存在更长的非递减子序列了,那么main直接退出

代码:

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<sstream>
#include<algorithm>
#include<iostream>
#include<stack>
#include<vector>
#include<set>
#include<map>

using namespace std;

const int maxn = 1001;
typedef long long ll;

int a[maxn],s[maxn];
int n,p,cnt;
void dfs(int last,int now,int len)
{

   if(n-last < len - now) return;
    if(cnt >= p) return;
    if(now == len)
    {
        // 输出
        cnt++;
        printf("%d",s[0]);
        for(int i=1; i<now; i++)
            printf(" %d",s[i]);
        printf("\n");
        return;
    }
    for(int i=last+1; i<=n; i++)
    {
        // 不够长度len,继续查找
        if(now >0 && a[i] < s[now-1])
            continue;
        int mark = 0;
        for(int j=last+1; j<i; j++)
        {
            if(a[i] == a[j])
            {
                mark = 1;
                break;
            }
        }
        if(mark)
            continue;
        s[now] = a[i];
        dfs(i,now+1,len);
        if(cnt == p)
            return;
    }

}
int main()
{
    int cas = 1;
    while(scanf("%d%d",&n,&p) == 2)
    {
        for(int i=1; i<=n; i++)
            scanf("%d",&a[i]);
        s[0] = 0;
        cnt = 0;
        for(int leng = 1; leng < n; leng++)
        {
            int judge = cnt;
            dfs(0,0,leng);
            if(judge == cnt ||cnt >= p)
                break;
        }
        printf("\n");
    }
    return 0;
}

HDU Fling

最近深搜写的乱七八糟,但是都莫名其妙能过hhhhh,这篇完结,接着回去刷状压DP

感觉这个代码写得还阔以

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cstring>
#include <queue>

using namespace std;
const int maxn = 10;
const int inf = 0x3f3f3f3f;

char mp[maxn][maxn];

struct Node
{
    int z,x,y;
};

vector<Node>ans;

int all;
int flag = 0;

int dir[4][2] = {-1,0,0,-1,0,1,1,0};
void dfs1(int now);

void dfs(int x,int y,int z, int now, int step)
{
    mp[x][y] = 'X';
    int nx = x+dir[z][0], ny = y+dir[z][1];
    while(mp[nx][ny] == 'X' && nx>=1&& nx<=7 && ny>=1 && ny<=8)
    {
        nx = nx + dir[z][0];
        ny = ny + dir[z][1];
    }
    if(mp[nx][ny] == 'O')
    {
        mp[nx-dir[z][0]][ny-dir[z][1]] = 'O';
        dfs(nx,ny,z,now,step+1);
        mp[nx-dir[z][0]][ny-dir[z][1]] = 'X';
        mp[x][y] = 'O';
    }
    else
    {
        if(step == 0)
        {
            mp[x][y] = 'O';
            return;
        }
        dfs1(now+1);
        mp[x][y] = 'O';
    }
}

int check()
{
    int cnt = 0;
    for(int i=1; i<=7; i++)
    {
        for(int j=1; j<=8; j++)
        {
            if(mp[i][j] == 'O')
            {
                cnt++;
                if(cnt == 2)
                    return 0;
            }
        }
    }
    return 1;
}
void dfs1(int now) // 开始拉一下
{
    if(check())
    {
        for(int t=0; t<ans.size(); t++)
        {
            // cout<<ans[t].first<<endl;
            //cout<<ans[t].z<<endl;
            char ch ;
            if(ans[t].z == 0)
                ch = 'U';
            else if(ans[t].z == 1)
                ch = 'L';
            else if(ans[t].z == 2)
                ch = 'R';
            else ch = 'D';
            printf("%d %d %c\n",ans[t].x-1,ans[t].y-1,ch);
        }
       // cout<<"finish!"<<endl;
        flag = 1;
        return;
    }
    for(int i=1; i<=7; i++)
    {
        for(int j=1; j<=8; j++)
        {
            if(mp[i][j] == 'O')
            {
                for(int z=0; z<4; z++)
                {
                    int nx = i+dir[z][0];
                    int ny = j+dir[z][1];
                    if(mp[nx][ny] != 'O' && nx>=1&& nx<=7 && ny>=1 && ny<=8)
                    {
                        //ans[now] = make_pair(z,make_pair(i,j));
                        Node p;
                        p.z = z;
                        p.x = i;
                        p.y = j;
                        ans.push_back(p);
                        dfs(i,j,z,now+1,0);
                        ans.pop_back();
                        if(flag == 1)
                            return;
                    }
                }
            }
        }
    }
}

int main()
{   int cas = 1;

    while(scanf("%s",mp[1]+1) != EOF)
    {

        flag = 0;
        for(int i=2; i<=7; i++)
            scanf("%s",mp[i]+1);
        for(int i=1; i<=7; i++)
        {
            for(int j=1; j<=8; j++)
                if(mp[i][j] == 'O')
                {
                    all++;
                }
        }
        if(cas != 1)
            cout<<endl;
        printf("CASE #%d:\n",cas++);

        //cout<<all<<endl;
        dfs1(0);


    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_37591656/article/details/81431753