区域判断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;

    }

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

原文地址:https://www.cnblogs.com/xinyuyuanm/p/3049921.html