zoukankan      html  css  js  c++  java
  • Codeforces 934.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
    4
    1 2 1 2
    output
    4
    input
    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组成的序列,要求翻转一个区间,使得最长不下降子序列尽可能长.

    分析:读错题坑了我40分钟.子序列可以不连续!

       考虑没有翻转操作.那么答案肯定是一个位置左边的1的数量+右边的2的数量,取max. 那么我们可以统计1的前缀和,2的后缀和.

       如果有翻转操作.其实就是翻转的区间中的一个位置统计1的后缀和,同时在这个位置统计2的前缀和,最后和两个端点处的相减.

    具体来说,如果记sum1为1的前缀和,sum2为2的后缀和,sum3为1的后缀和,sum4为2的前缀和,翻转的两个区间端点为a,b.那么答案就是max{sum1[a - 1] + sum2[b + 1] + sum3[i + 1] - sum3[b + 1] + sum4[i] - sum4[a - 1]}.实际上变动的就是sum3[i + 1]与sum4[i],求出一个区间内它们的最大值,有很多方法.我偷懒用线段树维护.

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    typedef long long ll;
    
    int n,a[2010],ans,f[2010][2010],sum1[2010],sum2[2010],sum3[2010],sum4[2010],b[2010],maxx[2010 << 2];
    
    void pushup(int o)
    {
        maxx[o] = max(maxx[o * 2],maxx[o * 2 + 1]);
    }
    
    void build(int o,int l,int r)
    {
        if (l == r)
        {
            maxx[o] = b[l];
            return;
        }
        int mid = (l + r) >> 1;
        build(o * 2,l,mid);
        build(o * 2 + 1,mid + 1,r);
        pushup(o);
    }
    
    int query(int o,int l,int r,int x,int y)
    {
        if (x <= l && r <= y)
            return maxx[o];
        int mid = (l + r) >> 1,res = -100000000;
        if (x <= mid)
            res = max(res,query(o * 2,l,mid,x,y));
        if (y > mid)
            res = max(res,query(o * 2 + 1,mid + 1,r,x,y));
        return res;
    }
    
    int main()
    {
        scanf("%d",&n);
        for (int i = 1; i <= n; i++)
            scanf("%d",&a[i]);
        for (int i = 1; i <= n; i++)
            sum1[i] = sum1[i - 1] + (a[i] == 1 ? 1 : 0);
        for (int i = n; i >= 1; i--)
            sum2[i] = sum2[i + 1] + (a[i] == 2 ? 1 : 0);
        for (int i = n; i >= 1; i--)
            sum3[i] = sum3[i + 1] + (a[i] == 1 ? 1 : 0);
        for (int i = 1; i <= n; i++)
            sum4[i] = sum4[i - 1] + (a[i] == 2 ? 1 : 0);
        for (int i = 0; i <= n; i++)
            b[i] = sum4[i] + sum3[i + 1];
        build(1,0,n);
        for (int i = 1; i <= n; i++)
        {
            for (int j = i; j <= n; j++)
            {
                int temp = query(1,0,n,i - 1,j);
                ans = max(ans,sum1[i - 1] + sum2[j + 1] + temp - sum3[j + 1] - sum4[i - 1]);
            }
        }
        printf("%d
    ",ans);
    
        return 0;
    }
  • 相关阅读:
    【摘录】使用实体框架、Dapper和Chain的仓储模式实现策略
    关于微软HttpClient使用,避免踩坑
    在网上摘录一段对于IOC的解析,比较直观,大家观摩观摩
    经历招聘中面试求职的点滴
    在面试中忽然发现DateTime的一些...
    GCC的内存边界对齐
    如何删除Weblogic域
    电蚊拍选购参考
    Localizing WPF with .resx files
    C#操作串口总结
  • 原文地址:https://www.cnblogs.com/zbtrs/p/8449283.html
Copyright © 2011-2022 走看看