• Codeforces Round #462 (Div. 2) C. A Twisty Movement (前缀和)


    C. A Twisty Movement

    time limit per test
    1 second
    memory limit per test
    256 megabytes
    input
    standard input
    output
    standard output

    A dragon symbolizes wisdom, power and wealth. On Lunar New Year's Day, people model a dragon with bamboo strips and clothes, raise them with rods, and hold the rods high and low to resemble a flying dragon.

    A performer holding the rod low is represented by a 1, while one holding it high is represented by a 2. Thus, the line of performers can be represented by a sequence a1, a2, ..., an.

    Little Tommy is among them. He would like to choose an interval [l, r] (1 ≤ l ≤ r ≤ n), then reverse al, al + 1, ..., ar so that the length of the longest non-decreasing subsequence of the new sequence is maximum.

    A non-decreasing subsequence is a sequence of indices p1, p2, ..., pk, such that p1 < p2 < ... < pk and ap1 ≤ ap2 ≤ ... ≤ apk. The length of the subsequence is k.

    Input

    The first line contains an integer n (1 ≤ n ≤ 2000), denoting the length of the original sequence.

    The second line contains n space-separated integers, describing the original sequence a1, a2, ..., an (1 ≤ ai ≤ 2, i = 1, 2, ..., n).

    Output

    Print a single integer, which means the maximum possible length of the longest non-decreasing subsequence of the new sequence.

    Examples
    input
    Copy
    4
    1 2 1 2
    output
    4
    input
    Copy
    10
    1 1 2 2 2 1 1 2 2 1
    output
    9
    Note

    In the first example, after reversing [2, 3], the array will become [1, 1, 2, 2], where the length of the longest non-decreasing subsequence is 4.

    In the second example, after reversing [3, 7], the array will become [1, 1, 1, 1, 2, 2, 2, 2, 2, 1], where the length of the longest non-decreasing subsequence is 9.

    题意就是在给出来的字符串里,找到一个最长非递增子串 把它倒序,使得整个字符串存在一个最长的非递减子串。并输出长度。

    这个题一开始看起来非常棘手,因为暴力很难切入,但是因为字符串里只有1和2,而且这个子串一定是222222222222221111111111111形式的,那么我们只要找到这个子串分界的地方就好了,我把最后一个2(就是1前面那个2)标记成k,然后枚举这个子串的首尾(l,r)因为1在前,2在后,我们需要维护一个1的前缀和pre1[]和2的后缀和aft2[],然后有点类似dp一样的形式找最大长度。

    需要注意的是分界点的长度计算,我是用2分界的,那么因为开头一定是2.分界点k左边需要求1的前缀和以及[l,k]之间2的个数 即 pre1[l]+aft2[l]-aft2[k+1] (+1是因为分界点就是2 不然会少算一个2),分界点k右边需要求2的后缀和以及[k,r]之间1的个数 即 aft2[r+1]+pre[r]-pre[k] (+1是因为分界点是2,不然会多算一个2(比方说数据里全是2)),然后找到最大的就行了。(这个真的很操蛋,一定要在草稿纸上模拟清楚),以下是改了一个多小时的成果:

    #include<bits/stdc++.h>
    
    using namespace std;
    
    int a[2005],pre1[2005],aft2[2005];
    int n;
    
    int main()
    {
        cin>>n;
        for(int i=1; i<=n; i++)
        {
            cin>>a[i];
            pre1[i]=pre1[i-1]+(a[i]==1);
        }
        for(int i=n; i>=1; i--)
            aft2[i]=aft2[i+1]+(a[i]==2);
        int ans=0;
        int kk,s1,s2;
        for(int k=1; k<=n; k++)
        {
            int sum1=0,sum2=0;
            for(int l=1; l<=k; l++) sum1=max(sum1,pre1[l]+aft2[l]-aft2[k+1]);
            for(int r=k; r<=n; r++) sum2=max(sum2,aft2[r]+pre1[r]-pre1[k]);
            ans=max(ans,sum1+sum2);
            /*if(ans<sum1+sum2)
            {
                ans=sum1+sum2;
                kk=k;
                s1=sum1;
                s2=sum2;
            }*/
        }
        //cout<<s1<<" "<<s2<<" "<<kk<<endl;
        cout<<ans<<endl;
        return 0;
    }
    View Code
  • 相关阅读:
    12、SpringBoot-CRUD增加数据
    12、SpringBoot-CRUD增加数据
    Cache操作类
    pythonhttp
    python学习
    自动化测试LoadRunner
    pythonweb自动化测试
    python学习工具篇
    python学习
    自动化测试之python安装
  • 原文地址:https://www.cnblogs.com/youchandaisuki/p/8727866.html
Copyright © 2020-2023  润新知