• DFS系列 POJ(自认为的讲解)


    C - Sum It Up POJ1564
    题意:
    给你一个N,然后给你一堆数The numbers in each list appear in nonincreasing order, and there may be repetitions.,让你在这对数里找出一些数,如果他们的和sum==N,则按样例的格式数输出。
    思路:
    那就是DFS呗,深搜一波,当sum==N时就输出,这里有一个就是排除重复的剪枝。为什么呢?

    #include<iostream>
    #include<cstdio>
    #include<stdlib.h>
    #include<vector>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    typedef long long LL;
    #define INF 0x3f3f3f3f
    #define N 1010
    
    
    int d[N];
    int a[N];
    int n,m;
    int flag;
    
    void dfs(int num,int sum,int v)
    {
        if(sum==n)
        {
            flag=1;
            printf("%d",d[0]);
            for(int i=1;i<num;i++)
            {
                printf("+%d",d[i]);
            }
            printf("
    ");
        }
        if(sum>n)
            return;
        for(int i=v;i<m;i++)
        {
            d[num]=a[i];
            dfs(num+1,sum+a[i],i+1);
            while(a[i]==a[i+1]&&i<m-1) //判重
                i++;
        }
    }
    
    int main()
    {
        while(~scanf("%d%d",&n,&m)&&n&&m)
        {
            for(int i=0;i<m;i++)
                scanf("%d",&a[i]);
            printf("Sums of %d:
    ",n);
            flag=0;
            dfs(0,0,0);
            if(!flag)
                printf("NONE
    ");
        }
        return 0;
    }

    D - 迷宫问题 poj3984

    题意:中文…
    思路:
    这道题推荐BFS+手写队列(这是很重要的)+路径输出,路径输出怎么讲解呢?
    (某些非正规定义的词语,是本菜鸡自己定义的)
    可以自己模拟一下,在一个队列里,我们用当前元素的pre记录上面那个元素在队列里的节点。最开始我们知道是左上角,所以就初始化他的pre值为-1,最后到了终点,就递归输出。
    这里用手写队列不仅跑的飞快而且非常省时间。可以感受一下。
    那么我们为什么要用STL的queue呢?知道了,请告诉我!谢谢!(学长说用STL简单方便)

    #include<iostream>
    #include<cstdio>
    #include<stdlib.h>
    #include<vector>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    typedef long long LL;
    #define INF 0x3f3f3f3f
    #define N 1010
    
    struct asd{
        int x,y;
        int pre;  //用来记录路径
    };
    asd q[25*10];
    int head,tail;
    int bmap[6][6];
    bool vis[6][6];
    int dx[4]={0,0,1,-1};
    int dy[4]={1,-1,0,0};
    
    void shuchu(int x)
    {
        if(q[x].pre==-1)
        {
            printf("(%d, %d)
    ",q[x].x,q[x].y);
        }
        else
        {
            shuchu(q[x].pre);
            printf("(%d, %d)
    ",q[x].x,q[x].y);
        }
    }
    
    void bfs()
    {
        head=0;tail=1;
        q[head].x=0;
        q[head].y=0;
        q[head].pre=-1;
        memset(vis,0,sizeof(vis));
        vis[0][0]=1;
        while(head<tail)
        {
            int bx,by;
            bx=q[head].x;
            by=q[head].y;
            if(bx==4&&by==4)
            {
                shuchu(q[head].pre);
                return;
            }
            for(int i=0;i<4;i++)
            {
                int aa=bx+dx[i];
                int bb=by+dy[i];
                if(aa<0||bb<0||aa>4||bb>4||vis[aa][bb]||bmap[aa][bb])
                    continue;
                vis[aa][bb]=1;
                q[tail].pre=head;
                q[tail].x=aa;
                q[tail].y=bb;
                tail++;
            }
            head++;
        }
    }
    
    int main()
    {
        for(int i=0;i<5;i++)
        {
            for(int j=0;j<5;j++)
                scanf("%d",&bmap[i][j]);
        }
        bfs();
        printf("(4, 4)
    ");
        return 0;
    }

    E – Sticks poj1011

    题意:给你一堆棒子,这些棒子是你从一堆一样的棒子折断而来的,现在你忘记了是从那一堆一样的棒子的长度,让你写一个程序,求最短的长度
    思路:
    讲道理这题的思路,好难讲。
    DFS也是非常混乱,剪枝也是.。
    与其说是找不到这种所谓的强有力的剪枝,不如说是自己思路不够全面。
    其实剪枝就是,尽可能地少去运行不必要的相同条件的路。
    好吧,还是来谈谈这道题的体会。
    我们可以发现因为all parts became at most 50 units long,而且there are at most 64 sticks,那么原始的长度最长也就是320,那么我们就有理由可以尝试枚举长度,然后去判断是否是最小的长度。

    我们可以进行排序,从而大大减少递归次数;(倒序)
    为什么是倒序,因为棒子越长的话越不灵活;所以我们是有依据采用倒序的

    那么出现一个剪枝:这个满足的长度L,一定满足棒子的总和sum%L==0这个条件。

    而且我们还可以想到以判除重复的条件剪枝,即在此刻没有条件的话,就没必要再去对这个相同的棒子去DFS。

    #include<iostream>
    #include<cstdio>
    #include<stdlib.h>
    #include<vector>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    typedef long long LL;
    #define INF 0x3f3f3f3f
    #define N 70
    
    int len[N];
    int n;
    int flag,k;
    bool vis[N];
    
    void dfs(int v,int sum,int num)
    {
        if(flag)
            return;
    
        if(sum==k)
        {
            if(num==n)
            {
                flag=1;
            }
            else
                dfs(0,0,num);
            return;
        }
        if(sum==0)
        {
            int v=0;           
            while(vis[v])
                v++;
            vis[v]=1;
            dfs(v+1,len[v],num+1);
            vis[v]=0;
            return;
        }
        for(int i=v; i<n; i++)
        {
            if(sum+len[i]<=k&&!vis[i])
            {
                if(len[i]==len[i-1]&&!vis[i-1])
                    continue;
                vis[i]=1;
                dfs(i+1,sum+len[i],num+1);
                vis[i]=0;
            }
        }
    }
    
    bool cmp(int a,int b)
    {
        return a>b;
    }
    
    int main()
    {
        int sum;
        int tmax;
        while(~scanf("%d",&n)&&n)
        {
            sum=0;
            tmax=-1;
            for(int i=0; i<n; i++)
            {
                scanf("%d",&len[i]);
                if(tmax<len[i])
                    tmax=len[i];
                sum+=len[i];
            }
            sort(len,len+n,cmp);
            for(k=tmax; k<=sum; k++)
            {
                if(sum%k==0)
                {
                    flag=0;
                    memset(vis,0,sizeof(vis));
                    dfs(0,0,0);
                    if(flag)
                    {
                        printf("%d
    ",k);
                        break;
                    }
                }
            }
        }
        return 0;
    }
  • 相关阅读:
    TClientDataSet[7]: 辨析 Field、FieldDef、Fields、FieldDefs、FieldList、FieldDefList
    TClientDataSet[11]: 分组统计
    TClientDataSet[14]: 测试 FindFirst、FindNext、FindLast、FindPrior、Found
    TClientDataSet[9]: 计算字段和 State
    这两天的收获
    又去北京
    关于博客园融资的想法
    《别为小事抓狂》读书笔记
    下周将去北京寻找投资
    服务器搬迁预告
  • 原文地址:https://www.cnblogs.com/keyboarder-zsq/p/5934550.html
Copyright © 2020-2023  润新知