CodeForces-447C DZY Loves Sequences

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int maxn = 1e5 + 5;
int num[maxn];      //原数列
int sign1[maxn];    //从开始标记
int sign2[maxn];    //从末尾标记
int n, ans;

int main()
{
    while(~scanf("%d", & n))
    {
        ans = 0;
        memset(num, 0, sizeof(num));            //初始化(主要是 num[0] = 0 num[n + 1] = 0)
        memset(sign1, 0, sizeof(sign1));
        memset(sign2,0, sizeof(sign2));
        for(int i = 1; i <= n; i ++)
            scanf("%d", & num[i]);              //输入n个数
        sign1[1] = 1;
        for(int i = 2; i <= n; i ++)            //sign1开始依次计数
        {
            if(num[i - 1] < num[i])
                sign1[i] = sign1[i - 1] + 1;
            else
                sign1[i] = 1;
        }
        sign2[n] = 1;
        for(int i = n - 1; i >= 1; i --)        //sign2开始依次计数
        {
            if(num[i] < num[i + 1])
                sign2[i] = sign2[i + 1] + 1;
            else
                sign2[i] = 1;
        }
        for(int i = 1; i <= n; i ++)            //有两种可能
        {
            if(num[i + 1] - num[i - 1] >= 2)    //1:两个连续的子序列可以连接
                ans = max(ans, sign1[i - 1] + sign2[i + 1] + 1);
            else                                //2: 两个子序列不能连接 取前后最大子列
                ans = max(ans, max(sign1[i - 1] + 1, sign2[i + 1] + 1));
        }
        printf("%d\n", ans);
    }
    return 0;
}

题意:
输入n,之后输入n个数。可以改变其中一个数。问改变后最大子序列长度多少。
题解:
也难说。来几个例子吧。其实可以从i = 0开始,不过看过去有点bug(i + 1 或者 i - 1 在i = n - 1 或者 i = 0会超范围),但是还是可以过。不过还是改成如上的代码。
num = 0 7 2 3 1 5 6 0 (实际前后各有一个0)
sign1 = 0 1 1 2 1 2 3 0
sign2 = 0 1 2 1 3 2 1 0
谈下前后设0的问题: i = 1 的时候,num[i - 1] = 0, num[i + 1] = 2, 符合条件则可以连接 0 + 1 + 1= 2。(把7变成1)
i = n 的时候,num[i - 1] = 5, num[i + 1] = 0, 不符合 >= 2,则取ans = max(ans, max(3, 0) = 3)。(已到末尾,只有取前面)
程序走到了1(i = 4)后, 5 - 3 = 2符合,则连接——sign1[3] = 2, sign2[4] = 2, 则长度为 2 + 2 + 1 = 5。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值