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; }