Codeforces - 1033C - Permutation Game - 简单dp

https://codeforces.com/problemset/problem/1033/C

一开始觉得自己的答案会TLE,但是吸取徐州赛区的经验去莽了一发。

其实因为下面这个公式是 $O(nlogn)$ 的,不是 $O(n²)$ ,所以这样做是可行的。学到了新的知识。

$$\sum\limits_{x=1}^{n}\lfloor\frac{n}{i}\rfloor$$

PS:学会LaTeX啦!

#include<bits/stdc++.h>
using namespace std;
#define ll long long

int res[100005];
int p[100005];
int a[100005];

int n;
void solve(int num,int c){
    for(int k=1;p[num]+k*num<=n;k++){
        if(a[p[num]+k*num]>num){
            if(res[a[p[num]+k*num]]==0){
                //存在一种转移到先手赢的情况?不应该让对方赢
                //存在一种转移到先手输的情况,转移过去自己就赢了
                //printf("%d can move to %d\n",num,a[p[num]+k*num]);
                res[num]=1;
                return;
            }
        }
    }
    for(int k=1;p[num]-k*num>=1;k++){
        if(a[p[num]-k*num]>num){
            if(res[a[p[num]-k*num]]==0){
                //存在一种转移到先手赢的情况?不应该让对方赢
                //存在一种转移到先手输的情况,转移过去自己就赢了
                //printf("%d can move to %d\n",num,a[p[num]-k*num]);
                res[num]=1;
                return;
            }
        }
    }
}

int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
        p[a[i]]=i;
    }

    res[n]=0;
    //先手赢=false
    for(int i=n-1;i>=1;i--){
        res[i]=0;
        //一开始假设没办法转移,先手赢=false
        solve(i,'A');
        if(res[i]==0){
            //printf("%d cannot move\n",i);
        }
    }

    for(int i=1;i<=n;i++){
        int t=a[i];
        if(res[t]==1){
            printf("A");
        }
        else{
            printf("B");
        }
    }

    printf("\n");
}

 2019-01-16

猜你喜欢

转载自www.cnblogs.com/Yinku/p/10279024.html