CF 555(DIV3) C2 Increasing Subsequence

题目链接:http://codeforces.com/contest/1157/my

题意:给你一个整数串,每次必须从最左端或者最右端取一个数按顺序放在子串里,且必须严格单增

求子串最大长度为多少,并且说出每一步的选择

分析:首先考虑相等,当左右两端相等时,很明显,以后只能从固定的一端选了

比如说,你选了左边,之后选的必须比之前选的大,那么最右端的你就不可能选了。

所以遇到了相等情况,我们就分别考虑左右,一条路走到黑,看最多能走多少次。

注意:因为是没回合都必须做出选择,只要有一回合不满足,就直接不满足了。

不相等的情况就直接左右比较即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;//这个数是1e9数量级的,且可以用memset函数 
const int maxn=2e5+7;
const double pi=acos(-1);
const int mod=1e9+7;
int a[maxn],ans[maxn];
int main(){
    ll n;scanf("%I64d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    int l=1,r=n,last=0,cnt=0;
    while(l<=r){
        if(a[l]==a[r]){
            if(a[l]<=last) break;//这里不要忘了加等号 
            int t1=1,t2=1;//t1,t2都从0开始是因为左右最起码会取一个 
            for(int i=l+1;i<r;i++){
                if(a[i]>a[i-1]) t1++;
                else break;
            }
            for(int i=r-1;i>l;i--){
                if(a[i]>a[i+1]) t2++;
                else break;
            }
            if(t1>=t2){
                for(int i=0;i<t1;i++){
                    ans[++cnt]=0;
                }
            }
            else for(int i=0;i<t2;i++)
                    ans[++cnt]=1;
            //出现相同的之后就会一次性全部处理完(因为只会从一边取了)故结束后直接跳出循环        
            break;        
        }
        else if(a[l]>last&&(a[l] < a[r] || a[r] <= last)){
            last=a[l];
            ans[++cnt]=0;
            l++;
        }
        else if(a[r]>last){
            last=a[r];
            ans[++cnt]=1;
            r--;
        }
        else break;
    }
    printf("%d
",cnt);
    for(int i=1;i<=cnt;i++){
        if(!ans[i])putchar('L');
        else putchar('R');
    }
    putchar('
');
    return 0;
}
原文地址:https://www.cnblogs.com/qingjiuling/p/10800629.html