Lyft Level 5 Challenge 2018 - Elimination Round C. Permutation Game (博弈,dp)
-
题意:有一个长度为\(n\)的排列,A和B进行博弈,每次操作可以在当前数\(a_i\)的基础移动到另一个位置,但是新的位置上的数\(a_j>a_i\)且\(|i-j|\) mod \(a_i\)=0.A先手,问你所有\([1,n]\)的情况中,A从\(i\)开始的结局情况.
-
题解:因为\(a_i\)每次只能移动到比自己大的数的位置,所以我们可以从\(n\)开始倒着枚举,那么所有比\(a_i\)大的数的情况都是确定的,用pair存值和位置,排个序,每次跑\(\frac{n}{n},\frac{n}{n-1},...,\frac{n}{1}\).根据调和级数,复杂度为\(O(nlogn)\).
-
代码:
#include <bits/stdc++.h> #define ll long long #define fi first #define se second #define pb push_back #define me memset #define rep(a,b,c) for(int a=b;a<=c;++a) #define per(a,b,c) for(int a=b;a>=c;--a) const int N = 1e6 + 10; const int mod = 1e9 + 7; const int INF = 0x3f3f3f3f; using namespace std; typedef pair<int,int> PII; typedef pair<ll,ll> PLL; ll gcd(ll a,ll b) {return b?gcd(b,a%b):a;} ll lcm(ll a,ll b) {return a/gcd(a,b)*b;} int main() { ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); int n; cin>>n; vector<PII> p(n+1); vector<int> res(n+1); rep(i,1,n){ cin>>p[i].fi; p[i].se=i; } sort(p.begin()+1,p.end(),greater<PII>()); rep(i,1,n){ if(p[i].se+p[i].fi>n && p[i].se-p[i].fi<1){ res[p[i].se]=2; continue; } rep(j,1,n){ int cur=p[i].se+j*p[i].fi; if(cur>n) break; if(res[cur]){ if(res[cur]==2){ res[p[i].se]=1; break; } } } rep(j,1,n){ int cur=p[i].se-j*p[i].fi; if(cur<1) break; if(res[cur]){ if(res[cur]==2){ res[p[i].se]=1; break; } } } if(res[p[i].se]!=1) res[p[i].se]=2; } rep(i,1,n){ if(res[i]==1) cout<<'A'; else cout<<'B'; } return 0; }
𝓐𝓬𝓱𝓲𝓮𝓿𝓮𝓶𝓮𝓷𝓽 𝓹𝓻𝓸𝓿𝓲𝓭𝓮𝓼 𝓽𝓱𝓮 𝓸𝓷𝓵𝔂 𝓻𝓮𝓪𝓵
𝓹𝓵𝓮𝓪𝓼𝓾𝓻𝓮 𝓲𝓷 𝓵𝓲𝓯𝓮