zoukankan      html  css  js  c++  java
  • 区域判断hdu 3681 Prison Break bfs+二分+dp

    时间紧张,先记一笔,后续优化与完善。

        这个是2010杭州区域赛的目题。

           bfs出最短路,二分谜底,dp判断可行性。

        

        #include <iostream>

        #include <cstdio>

        #include <cstring>

        using namespace std;

        const int maxn=17,maxm=300;

        int n,m,lon,ret;

        char a[maxn][maxn];

        int b[maxn],d[maxn][maxn];

        int quex[maxm],quey[maxm],text[maxn][maxn],f[maxn][maxn];

        int dp[1<<17][20];

        int work(int ans)

        {

        memset(dp,1,sizeof(dp));

        for(int i=0;i<lon;i++)

        if(d[16][i+1]<=ans)

        {

            dp[1<<i][i+1]=d[16][i+1];

            if(b[i+1]==1)

            dp[1<<i][i+1]=0;

        }

        for(int k=0;k<(1<<lon);k++)

        for(int i=0;i<lon;i++)

        for(int j=0;j<lon;j++)

        if(dp[k][i+1]+d[i+1][j+1]<=ans)

        {

            dp[k|(1<<j)][j+1]=min(dp[k|(1<<j)][j+1],dp[k][i+1]+d[i+1][j+1]);

            if(b[j+1]==1)

            if((k&(1<<j))==0)

            dp[k|(1<<j)][j+1]=0;

        }

        for(int k=0;k<(1<<lon);k++)

        if((k&((1<<ret)-1))==(1<<ret)-1)

        for(int i=1;i<=lon;i++)

        if(dp[k][i]<=ans)

        return(1);

        return(0);

        }

        void bfs(int t,int s)

        {

        memset(text,0,sizeof(text));

        memset(f,1,sizeof(f));

        f[t][s]=0;

        text[t][s]=1;

        int front=1,end=0;

        quex[++end]=t;

        quey[end]=s;

        int u=a[t][s];

        d[u][u]=0;

        while(front<=end)

        {

            int x=quex[front],y=quey[front++];

            if(a[x][y]=='D') continue;

            int v=a[x][y];

            if(v>=1&&v<=16)

            {

                d[u][v]=f[x][y];

                d[v][u]=f[x][y];

            }

            if(x>1)

            {

                if(f[x-1][y]>f[x][y]+1)

                {

                    f[x-1][y]=f[x][y]+1;

                    if(!text[x-1][y])

                    {

                        quex[++end]=x-1;

                        quey[end]=y;

                    }

                }

            }

            if(x<n)

            {

                if(f[x+1][y]>f[x][y]+1)

        每日一道理
    喜欢海,不管湛蓝或是光灿,不管平静或是波涛汹涌,那起伏荡漾的,那丝丝的波动;喜欢听海的声音,不管是浪击礁石,或是浪涛翻滚,那轻柔的,那澎湃的;喜欢看海,不管心情是舒畅的或是沉闷的,不管天气是晴朗的或是阴沉的,那舒心的,那松弛的……

                {

                    f[x+1][y]=f[x][y]+1;

                    if(!text[x+1][y])

                    {

                        quex[++end]=x+1;

                        quey[end]=y;

                    }

                }

            }

            if(y>1)

            {

                if(f[x][y-1]>f[x][y]+1)

                {

                    f[x][y-1]=f[x][y]+1;

                    if(!text[x][y-1])

                    {

                        quex[++end]=x;

                        quey[end]=y-1;

                    }

                }

            }

            if(y<m)

            {

                if(f[x][y+1]>f[x][y]+1)

                {

                    f[x][y+1]=f[x][y]+1;

                    if(!text[x][y+1])

                    {

                        quex[++end]=x;

                        quey[end]=y+1;

                    }

                }

            }

        }

        }

        int main()

        {

        //    freopen("in.txt","r",stdin);

        while(scanf("%d %d",&n,&m),n||m)

        {

            lon=0;

            for(int i=1;i<=n;i++)

            scanf("%s",&a[i][1]);

            for(int i=1;i<=n;i++)

            for(int j=1;j<=m;j++)

            if(a[i][j]=='Y')

            {

                a[i][j]=++lon;

                b[lon]=2;

            }

            else if(a[i][j]=='F')

            {

                a[i][j]=16;

            }

            ret=lon;

            for(int i=1;i<=n;i++)

            for(int j=1;j<=m;j++)

            if(a[i][j]=='G')

            {

                a[i][j]=++lon;

                b[lon]=1;

            }

            memset(d,1,sizeof(d));

            for(int i=1;i<=n;i++)

            for(int j=1;j<=m;j++)

            if(a[i][j]>=1&&a[i][j]<=16)

            bfs(i,j);

            int ture=0;

            for(int i=1;i<=ret;i++)

            if(d[16][i]>300)

            ture=1;

            if(ret==0)

            {

                printf("0\n");

                continue;

            }

            if(ture)

            {

                printf("-1\n");

                continue;

            }

            int st=0,ed=1000,mid;

            while(st<ed)

            {

                int mid=(st+ed)>>1;

                if(work(mid))

                ed=mid;

                else

                st=mid+1;

            }

            printf("%d\n",st);

        }

        return 0;

        }

    文章结束给大家分享下程序员的一些笑话语录: 自行车
    一个程序员骑着一个很漂亮的自行车到了公司,另一个程序员看到了他,问 到,“你是从哪搞到的这么漂亮的车的?”
    骑车的那个程序员说, “我刚从那边过来, 有一个漂亮的姑娘骑着这个车过来, 并停在我跟前,把衣服全脱了,然后对我说,‘你想要什么都可以’”。
    另一个程序员马上说到, “你绝对做了一个正确的选择, 因为那姑娘的衣服你 并不一定穿得了”。

  • 相关阅读:
    vs13的内存占用 关闭之
    Java基础 -5
    Java基础 -4.6
    Java基础 -4.5
    Java基础 -4.4
    Java基础 -4.3
    Java基础 -4.2
    Java基础 -4
    Java基础 -3.5
    Java基础 -3.4
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/3049921.html
Copyright © 2011-2022 走看看