Codeforces Round #206 (Div. 1)B(记忆化)

这题刚开始理解错题意了 以为只能往右和下走 

这题挺好的 看题解看了N久啊 

二维的DP 第一维表示走到第几步 可以画一个正方形 以左上角斜着划线 第i步走的点只能是第i条线上的点 而dp的第二维 就表示的第i步可以到达的点的状态 

另开一个a数组来表示 第i条线上每个字母的状态 

dp所代表的值就为a与b的差值 以这个来进行选择 进行记忆化

确定下一步可以到达的字母的状态 是以当前可达的状态&下一步所要到达的字母的状态 

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<vector>
 7 using namespace std;
 8 #define LL __int64
 9 #define INF 1e9
10 int dp[42][1<<20],a[42][42];
11 char s[22][22];
12 int n;
13 int dfs(int step,int sta)
14 {
15     int i,num=0;
16     if(dp[step][sta]!=INF)
17     return dp[step][sta];
18     for(i = 0; i < n ; i++)
19     {
20         if(sta&(1<<i))
21         {
22             if(s[step-i][i]=='a') num++;
23             else if(s[step-i][i]=='b') num--;
24             break;
25         }
26     }
27     if(step==2*n-2)
28     return dp[step][sta] = num;
29     if(step%2!=0)
30     {
31         dp[step][sta] = -INF;
32         for(i = 0 ; i < 26 ; i++)
33         {
34             int next = a[step+1][i]&(sta|(sta<<1));
35             if(next==0)
36             continue;
37             dp[step][sta] = max(dp[step][sta],dfs(step+1,next)+num);
38         }
39         return dp[step][sta];
40     }
41     else
42     {
43         for(i = 0 ; i < 26 ; i++)
44         {
45             int next = a[step+1][i]&(sta|(sta<<1));
46             if(next==0)
47             continue;
48             dp[step][sta] = min(dp[step][sta],dfs(step+1,next)+num);
49         }
50         return dp[step][sta];
51     }
52 }
53 int main()
54 {
55     int i,j;
56     scanf("%d",&n);
57     for(i = 0 ; i < n ; i++)
58     cin>>s[i];
59     for(i = 0 ; i < 2*n-1 ; i++)
60     {
61         for(j = 0 ; j < n ; j++)
62         {
63             if(i-j<0||i-j>=n) continue;
64             a[i][s[i-j][j]-'a'] |= (1<<j);
65         }
66     }
67     for(i = 0 ; i < 2*n ; i++)
68         for(j = 0 ; j < (1<<n) ; j++)
69         dp[i][j] = INF;
70     int ans = dfs(0,1);
71     if(ans>0)
72     puts("FIRST");
73     else if(ans<0)
74     puts("SECOND");
75     else
76     puts("DRAW");
77     return 0;
78 }
View Code

posted @ 2013-10-20 12:55  _雨  阅读(218)  评论(0编辑  收藏  举报