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

你可能感兴趣的:(cpp)