思路:首先预处理出左右两端升序列的长度。考虑拿了i位置上的数后,当前数列左端和右端的数大小情况,如果两端的数都小于等于a[i]那么当前状态为毕败状态,如果只有一端的数大于 a [ i ] a[i] a[i]跟据这一端升序列的长度,可以直接判断当前状态为比胜还是必败状态。如果两端的数都大于 a [ i ] a[i] a[i],如果取较大的数,那么下次取数开始只能一直取那一端的数,如果取较小的数,重复以上过程可以 O ( n ) O(n) O(n)判断所有状态。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,a[200005],pre[200005],suf[200005];
void dfsl(int pos)
{
if(pos==n+1)return;
if(a[pos+1]>a[pos])dfsl(pos+1);
suf[pos]=suf[pos+1]+1;
}
void dfsr(int pos)
{
if(pos==0)return;
if(a[pos-1]>a[pos])dfsr(pos-1);
pre[pos]=pre[pos-1]+1;
}
int dfs(int now,int l,int r)
{
if(l==r)
{
if(a[l]>a[now])return 1;
return -1;
}
if(a[l]>a[now] && a[r]<=a[now])
{
if(suf[l]%2==0)return 1;
return -1;
}
if(a[r]>a[now] && a[l]<=a[now])
{
if(pre[r]%2==0)return 1;
return -1;
}
if(a[l]>=a[now] && a[r]>=a[now])
{
int lson,rson;
if(a[l]<=a[r])
{
if(pre[r]%2==1)rson=1;
else rson=-1;
lson=dfs(l,l+1,r);
}
else
{
if(suf[l]%2==1)lson=1;
else lson=-1;
rson=dfs(r,l,r-1);
}
if(lson==-1 && rson==-1)return 1;
return -1;
}
return 1;
}
int main()
{
ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
dfsl(1);
dfsr(n);
if(n==1)cout<<"Alice"<<endl;
else if(dfs(1,2,n)==1 || dfs(n,1,n-1)==1)cout<<"Alice"<<endl;
else cout<<"Bob"<<endl;
return 0;
}