D. Letter Picking
time limit per test
2 seconds
memory limit per test
512 megabytes
input
standard input
output
standard output
Alice and Bob are playing a game. Initially, they are given a non-empty string ss, consisting of lowercase Latin letters. The length of the string is even. Each player also has a string of their own, initially empty.
Alice starts, then they alternate moves. In one move, a player takes either the first or the last letter of the string ss, removes it from ss and prepends (adds to the beginning) it to their own string.
The game ends when the string ss becomes empty. The winner is the player with a lexicographically smaller string. If the players' strings are equal, then it's a draw.
A string aa is lexicographically smaller than a string bb if there exists such position ii that aj=bjaj=bj for all j<ij<i and ai<biai<bi.
What is the result of the game if both players play optimally (e. g. both players try to win; if they can't, then try to draw)?
Input
The first line contains a single integer tt (1≤t≤10001≤t≤1000) — the number of testcases.
Each testcase consists of a single line — a non-empty string ss, consisting of lowercase Latin letters. The length of the string ss is even.
The total length of the strings over all testcases doesn't exceed 20002000.
Output
For each testcase, print the result of the game if both players play optimally. If Alice wins, print "Alice". If Bob wins, print "Bob". If it's a draw, print "Draw".
Example
input
Copy
2
forces
abba
output
Copy
Alice Draw
Note
One of the possible games Alice and Bob can play in the first testcase:
- Alice picks the first letter in ss: s=s="orces", a=a="f", b=b="";
- Bob picks the last letter in ss: s=s="orce", a=a="f", b=b="s";
- Alice picks the last letter in ss: s=s="orc", a=a="ef", b=b="s";
- Bob picks the first letter in ss: s=s="rc", a=a="ef", b=b="os";
- Alice picks the last letter in ss: s=s="r", a=a="cef", b=b="os";
- Bob picks the remaining letter in ss: s=s="", a=a="cef", b=b="ros".
Alice wins because "cef" < "ros". Neither of the players follows any strategy in this particular example game, so it doesn't show that Alice wins if both play optimally.
---------------------------------------------------------------------------------------------------------------------------------
A B每次从当前 S 首部或者尾部选择一个字母,删除这一字母,并且放在自己串的开头
典型的区间博弈DP,用短小区间更新大区间,最终答案为dp[1][n]
为了方便操作,设置DP值越小,对A越有利
0 初始值
1 A赢
2 平局
3 B输
初始化 长度为2的区间,因为A先手,所以只要是s[i]!=s[i+1],那么dp[i][i+1]就等于1 ,否则就为平局
然后开始进行区间DP,题目保证偶数,每次长度+2即可
设当前区间 [L,R],长度len ,由 len-2长度转移而来,A无非两种情况,
l或者r
选择l时 ,B无非两种选择 l+1, r中最优的,也就是最大的
选择r时 ,B无非两种选择 r-1 ,l中最优的,也就是最大的
而A就选择l,r中最优的,也就是最小的
值得注意的是,我们是最后选的防止在串开头,那么就以为这小区间答案的优先级高于大区间,比如小区间dp值为1 ,那么无论当前选择什么,小区间决定的当前dp值必定也为1
# include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
int dp[2010][2010];
string s;
int getf(int a,int b)
{
if(s[a]==s[b])
return 2;
if(s[a]<s[b])
return 1;
return 3;
}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>s;
int n=s.length();
s=" "+s;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
dp[i][j]=0; //无解
}
}
//设置 A赢为 1 平局为 2 B赢为3
for(int i=1;i<n;i++)
{
if(s[i]==s[i+1])
dp[i][i+1]=2;
else
dp[i][i+1]=1;
}
for(int len=4;len<=n;len+=2)
{
for(int i=1;i+len-1<=n;i++)
{
int l=i,r=i+len-1;
/* 当前A无非两种选择,l或者r
选择l时 ,B无非两种选择 l+1 r中最优的,也就是最大的
选择r时 ,B无非两种选择 r-1 l中最优的,也就是最大的
而A就选择l,r中最优的,也就是最小的
A选择l时*/
int ans1=1e9,ans2=1e9;
int temp1=getf(l,l+1); //仅考虑当前两个的情况
if(dp[l+2][r]==3) //前面一局优先级大于当前局
temp1=3;
else if(dp[l+2][r]==2)
temp1=temp1;
else if(dp[l+2][r]==1)
temp1=1;
int temp2=getf(l,r);
if(dp[l+1][r-1]==3)
temp2=3;
else if(dp[l+1][r-1]==2)
temp2=temp2;
else if(dp[l+1][r-1]==1)
temp2=1;
ans1=max(temp1,temp2);
temp1=getf(r,r-1);
if(dp[l][r-2]==3)
temp1=3;
else if(dp[l][r-2]==2)
temp1=temp1;
else if(dp[l][r-2]==1)
temp1=1;
temp2=getf(r,l);
if(dp[l+1][r-1]==3)
temp2=3;
else if(dp[l+1][r-1]==2)
temp2=temp2;
else
temp2=1;
ans2=max(temp1,temp2);
dp[l][r]=min(ans1,ans2);
}
}
if(dp[1][n]==1)
{
cout<<"Alice"<<endl;
}
else if(dp[1][n]==2)
{
cout<<"Draw"<<endl;
}
else
{
cout<<"Bob"<<endl;
}
}
return 0;
}