Codeforces 354B dp Game with Strings dp

Game with Strings

题意并不是在图上走,看了好久才看出来。。

dp[ i ][ mask ]表示从 i 层开始走,起点有mask个, a的个数-b的个数的  最大值或者最小值。

#include<bits/stdc++.h>
#define LL long long
#define LD long double
#define fi first
#define se second
#define mk make_pair
#define PLL pair<LL, LL>
#define PLI pair<LL, int>
#define PII pair<int, int>
#define SZ(x) ((int)x.size())
#define ull unsigned long long

using namespace std;

const int N = 20 + 7;
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
const double eps = 1e-8;
const double PI = acos(-1);

template<class T, class S> inline void add(T& a, S b) {a += b; if(a >= mod) a -= mod;}
template<class T, class S> inline void sub(T& a, S b) {a -= b; if(a < 0) a += mod;}
template<class T, class S> inline bool chkmax(T& a, S b) {return a < b ? a = b, true : false;}
template<class T, class S> inline bool chkmin(T& a, S b) {return a > b ? a = b, true : false;}

int n;
int dp[21 * 2][1 << 20];
bool vis[21 * 2][1 << 20];
char Map[30][30];
int id[30][30];

struct Point {
    int x, y;
};

vector<Point> vc[50];

int dfs(int d, int mask, int op) {
    if(d == n * 2 - 2) return 0;
    int& ans = dp[d][mask];
    if(vis[d][mask]) return ans;
    ans = op ? inf : -inf;
    int up = SZ(vc[d]);
    for(char c = 'a'; c <= 'z'; c++) {
        int nxtmask = 0, sco = 0;
        if(c == 'a') sco = 1;
        else if(c == 'b') sco = -1;
        for(int i = 0; i < up; i++) {
            if(mask >> i & 1) {
                int x = vc[d][i].x, y = vc[d][i].y + 1;
                if(y < n && Map[x][y] == c) {
                    nxtmask |= 1 << id[x][y];
                }
                x = vc[d][i].x + 1, y = vc[d][i].y;
                if(x < n && Map[x][y] == c) {
                    nxtmask |= 1 << id[x][y];
                }
            }
        }
        if(nxtmask) {
            if(op) chkmin(ans, dfs(d + 1, nxtmask, op ^ 1) + sco);
            else chkmax(ans, dfs(d + 1, nxtmask, op ^ 1) + sco);
        }
    }
    vis[d][mask] = true;
    return ans;
}

int main() {
    scanf("%d", &n);
    for(int i = 0; i < n; i++) scanf("%s", Map[i]);
    for(int i = 0; i < n; i++) {
        int x = i, y = 0;
        while(x < n && y < n && x >= 0 && y >= 0) {
            id[x][y] = SZ(vc[i]);
            vc[i].push_back(Point{x, y}), x--, y++;
        }
    }
    for(int i = n; i < 2 * n; i++) {
        int x = n - 1, y = i - n + 1;
        while(x < n && y < n && x >= 0 && y >= 0) {
            id[x][y] = SZ(vc[i]);
            vc[i].push_back(Point{x, y}), x--, y++;
        }
    }
    int judge = dfs(0, 1, 1);
    if(Map[0][0] == 'a') judge++;
    else if(Map[0][0] == 'b') judge--;
    if(judge > 0) puts("FIRST");
    else if(judge < 0) puts("SECOND");
    else puts("DRAW");
    return 0;
}

/*
*/

猜你喜欢

转载自www.cnblogs.com/CJLHY/p/10698348.html
今日推荐