zoukankan      html  css  js  c++  java
  • codeforces 447C. DZY Loves Sequences 解题报告(446A)

    题目链接:http://codeforces.com/problemset/problem/447/C

    题目意思:给出 一个 包含 n 个数的序列你,从中需要找出这个序列的最长子串,满足在里面只修改其中一个元素,使得这个子串的元素严格递增,求出这个长度是多少。

      以为是DP题(它的分类确实是DP题),无从下手。看了下别人写的,有些部分不太明白;根据自己的理解再结合一些别人的,加了些特判,总算过了^_^,我好像觉得我的做法不像是用了DP思想咯........

         总体思路就是:设两个数组,分别为inc_left[] 和 inc_right[],顾名思义,对于第 i 个元素,inc_left[i]就是从左到右扫描序列,到达这个inc_left[i]元素的时候,它的递增长度是多少。举个例子,对于test 1 中的   7  2  3   1  5   6

                      inc_left[i]为: 1  1  2   1   2   3

          对于6这个数来说,inc_left[6] = 3 是因为 1 5 6 严格递增。而为什么有些inc_left[i] = 1,是因为前面加上自己,不构成递增序列。inc_right[]依次类推。

          这两个数组结合起来就可以求出 2 3 1 5 6 的情况了,即对于某个a[i],只改变a[i]这个数,使得以这个a[i] 为原点,左右扩散起来,能够构成的最长递增序列。

          要注意一些特判,例如,当n  = 1 时直接输出1;如果输入序列本来已经严格递增,直接输出n。最后一种情况就是,1 1 这种,只改变其中一个元素,答案为2,代码中的

    ans = max(ans, max(inc_left[i]+1, inc_right[i]+1));   就是为了应对这种情况的。

        

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 using namespace std;
     6 
     7 const int N = 1e5 + 5;
     8 int a[N], inc_left[N], inc_right[N];
     9 
    10 int main()
    11 {
    12     int n;
    13     while (scanf("%d", &n) != EOF)
    14     {
    15         memset(a, 0, sizeof(a));
    16         for (int i = 1; i <= n; i++)
    17             scanf("%d", &a[i]);
    18         if (n == 1)
    19             printf("1
    ");
    20         else
    21         {
    22             int ans = 0;
    23             inc_left[1] = 1;
    24             for (int i = 2; i <= n; i++)
    25             {
    26                 inc_left[i] = (a[i] > a[i-1] ? inc_left[i-1]+1 : 1);
    27                 ans = max(ans, inc_left[i]);
    28             }
    29             inc_right[n] = 1;
    30             for (int i = n-1; i >= 1; i--)
    31             {
    32                 inc_right[i] = (a[i+1] > a[i] ? inc_right[i+1]+1 : 1);
    33                 ans = max(ans, inc_right[i]);
    34             }
    35             if (ans == n)  // 处理序列本来就是递增情况
    36                 printf("%d
    ", n);
    37             else
    38             {
    39                 for (int i = 1; i <= n; i++)
    40                 {
    41                     if (a[i+1] > a[i-1]+1)    // 这两种情况需排除:1 ? 2 或 1 ? 1,可以更改的至少需要满足1 ? 3
    42                         ans = max(ans, inc_right[i+1]+inc_left[i-1]+1);
    43                     else
    44                         ans = max(ans, max(inc_left[i]+1, inc_right[i]+1));  // 处理 1 1的情况,只能更改其中一个
    45                 }
    46                 printf("%d
    ", ans);
    47             }
    48         }
    49     }
    50     return 0;
    51 }
  • 相关阅读:
    ueditor精简插件和减少初次加载文件的方法
    The Art of Mocking
    What is a mocking framework? Why is it useful?
    黑盒测试、白盒测试、单元测试、集成测试、系统测试、验收测试的区别与联系
    What is the purpose of mock objects?
    What is Mocking?
    APPENDIX: How to apply the Apache License to your work
    开源 ≠ 免费,开源协议License详解
    如何选择开源许可证?
    五种开源协议的比较(BSD,Apache,GPL,LGPL,MIT) – 整理
  • 原文地址:https://www.cnblogs.com/windysai/p/3843642.html
Copyright © 2011-2022 走看看