标签:codeforces 博弈 dp
给出n个字符串,进行k次游戏,每次游戏输家下次作为先手,游戏规则为每次放一个字母,导致当前构造的字符串是给定的任意一个字符串的前缀,不能操作时为输,赢得第k次比赛的人会取得最终的胜利,问两人都采取最优策略的情况下,谁会赢得比赛。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define MAX 100007
using namespace std;
int n,k,cc;
char s[MAX];
struct Node
{
int branch[26];
Node ( )
{
memset ( branch , -1 , sizeof ( branch));
}
int win,lose;
}p[MAX<<1];
void add ( )
{
int u = 0;
int m = strlen ( s );
for ( int i = 0 ; i < m ; i++ )
{
int x = s[i]-‘a‘;
if ( p[u].branch[x] == -1 )
p[u].branch[x] = cc++;
u = p[u].branch[x];
}
}
void dfs ( int u , int d )
{
int temp1,temp2;
temp1 = temp2 = (d&1)?0:1;
bool flag = false;
for ( int i = 0 ; i < 26 ; i++ )
{
int v = p[u].branch[i];
if ( v == -1 ) continue;
flag = true;
dfs ( v , d+1 );
if ( d&1 )
{
temp1 = temp1||p[v].win;
temp2 = temp2||p[v].lose;
}
else
{
temp1 = temp1&&p[v].win;
temp2 = temp2&&p[v].lose;
}
}
if ( !flag )
{
p[u].win = p[u].lose = 0;
if ( d&1 ) p[u].lose = 1;
else p[u].win = 1;
}
else
{
p[u].win = temp1;
p[u].lose = temp2;
}
}
int main ( )
{
while ( ~scanf ( "%d%d" , &n , &k ))
{
cc = 1;
for ( int i = 0 ; i < n ; i++ )
{
scanf ( "%s" , s );
add ( );
}
dfs ( 0 , 1 );
int win = p[0].win;
int lose = p[0].lose;
if ( !win ) puts ( "Second");
else if ( lose ) puts ("First");
else
{
if ( k&1 ) puts ("First");
else puts ("Second");
}
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:codeforces 博弈 dp
原文地址:http://blog.csdn.net/qq_24451605/article/details/48650207