Hlg 1709 巧妙思维题.cpp

题意:

  给出n个数,求出改变某个数后能得到最长的严格上升子序列

思路:

  用一个数组pre[i]和suf[i]分别表示第i个数前的严格上升子序列有多长,第i个数后的严格上升子序列有多长

  如果arr[i]的前一个数比后一个数起码小1的话..找出max(pre[i]+suf[i]+1),否则max(ans, max(suf[i]+1, pre[i]+1))

Tips:

  注意可能出现1 1 2 3 4 这样的情况,这时候就只能是4了..

Code:

View Code
 1 #include <stdio.h>
 2 #include <cstring>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 int main()
 7 {
 8     int n;
 9     int arr[10010], pre[10010], suf[10010];
10     int ans;
11     while(~scanf("%d", &n)) {
12         ans = -1;
13         memset(pre, 0, sizeof(pre));
14         memset(suf, 0, sizeof(suf));
15         for(int i = 0; i < n; ++i) {
16             scanf("%d", &arr[i]);
17             int j = i-2;
18             while(j >= 0 && arr[j] < arr[j+1]) j--;
19             pre[i] = i-j-1;
20             if(i == 0) pre[i] = 0;
21         }
22         for(int i = 0; i < n; ++i) {
23             int j = i+2;
24             while(j < n && arr[j-1] < arr[j]) j++;
25             suf[i] = j-i-1;
26             if(i == n-1) suf[i] = 0;
27         }
28     /*********************debug******************
29     for(int i = 0; i < n; ++i)
30         printf("____%d %d\n", pre[i], suf[i]);
31     *********************debug******************/
32         for(int i = 0; i < n; ++i)
33             if(arr[i-1] < arr[i+1]-1)
34                 ans = max(ans, pre[i]+suf[i]+1);
35             else if(i != 1 || (i == 1 && arr[i] != 0)) ans = max(ans, max(suf[i]+1, pre[i]+1));
36        // if(arr[1] != 1) ans = max(ans, suf[0]+1);
37         printf("%d\n", ans);
38     }
39     return 0;
40 }

链接:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=1709

原文地址:https://www.cnblogs.com/Griselda/p/3011098.html