zoukankan      html  css  js  c++  java
  • D. Game with Strings

    http://codeforces.com/contest/355/problem/D

    这道题问了一下学妹,难道说哥已经老了!!!

    首先题意理解上有些问题 比如说

    a   b    c

    b   d    e

    f    g    h

    第一个人写下 a ,第二个人写下 b,然后又该第一个人写了,这时候的 b 既可以是上边的 b

    也可以是下边的 b 由将要写的人决定

    dp[n][1<<20] 中dp[x][y] 表示的意思是到第x步时,选y这个状态为结尾(所对应的字符都相等)

    且前面的字符串都一样时,接下来怎么选出的最优解

    代码:

    #include<iostream>
    #include<stack>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<set>
    #include<map>
    #include<string>
    #include<cmath>
    
    using namespace std;
    
    typedef long long ll;
    typedef pair<int,int> pp;
    const double eps=1e-6;
    const int INF=0x3f3f3f3f;
    const int N=41;
    int dp[N][1<<20];
    char c[N][N];
    int a[N][N];
    int n;
    int dfs(int x,int y)
    {
        if(dp[x][y]!=INF)
        return dp[x][y];
        int w=(y|(y<<1));
        int s[26]={0};
        for(int h=0,x1=x,y1=1;h<n;++h,x1--,y1++)
        if((y&(1<<h))&&x1>=1&&y1<=n)
        {dp[x][y]=a[x1][y1];break;}
        if(x==2*n-1)
        return dp[x][y];
        for(int h=0,x1=x+1,y1=1;h<n;++h,x1--,y1++)
        if((w&(1<<h))&&x1>=1&&y1<=n)
        {
            int t=c[x1][y1]-'a';
            s[t]=(s[t]|(1<<h));
        }
        int k0=-INF,k1=INF;
        for(int i=0;i<26;++i)
        if(s[i]>0)
        {
            k0=max(k0,dfs(x+1,s[i]));
            k1=min(k1,dfs(x+1,s[i]));
        }
        if((x&1))
        dp[x][y]+=k1;
        else
        dp[x][y]+=k0;
        return dp[x][y];
    }
    int main()
    {
        //freopen("data.in","r",stdin);
    
        while(cin>>n)
        {
            int m=(1<<n);
            for(int i=0;i<N;++i)
            for(int j=0;j<m;++j)
            dp[i][j]=INF;
            memset(c,0,sizeof(c));
            memset(a,0,sizeof(a));
            for(int i=1;i<=n;++i)
            for(int j=1;j<=n;++j)
            {
                cin>>c[i][j];
                if(c[i][j]=='a') a[i][j]=1;
                if(c[i][j]=='b') a[i][j]=-1;
            }
            int k=dfs(1,1);
            //cout<<k<<endl;
            if(k>0)
            cout<<"FIRST"<<endl;
            if(k<0)
            cout<<"SECOND"<<endl;
            if(k==0)
            cout<<"DRAW"<<endl;
        }
        //fclose(stdin);
        return 0;
    }
    
  • 相关阅读:
    Linux上查找
    Linux进程
    Linux重定向
    Linux上常用的基本命令
    LInux上返回到切换目录前的目录
    【网络知识之一】4/7层网络模型
    【操作系统之十五】iptables黑白名单、自定义链、网络防火墙、常用动作
    【操作系统之十四】iptables扩展模块
    【操作系统之十三】Netfilter与iptables
    【操作系统之十二】分支预测、CPU亲和性(affinity)
  • 原文地址:https://www.cnblogs.com/liulangye/p/3411234.html
Copyright © 2011-2022 走看看