codeforces 446A DZY Loves Sequences
vjudge 上题目链接:codeforces 446A
大意是说最多可以修改数列中的一个数,求最长严格递增的连续子序列长度。
其实就是个 dp 的思想,想好思路后交上去没想到一直 wa 在第二个测试数据里,丧心病狂啊 T.T,后来才知道原来是分类讨论时没考虑全,而且下标也写拙了。
情况有三:
(1) 不作任何修改,直接遍历一遍求出的 in 数组和 de 数组即可。(其实这种情况不会优于(3),可以不用考虑)
(2) 修改的元素为最长递增子序列的中间结点,把左边的 in[i - 1] 加上右边的 de[i + 1] 再 +1 即原本这个元素。
(3) 修改的元素为最长递增子序列的首尾结点,所以这时候的值就是 in[i - 1] +1 或 de[i + 1] +1。(就是遗漏了这种情况啊,md)
然后,下标也要很注意,i 须取到 1 和 n;还要特判一下 n == 2 的情况,否则还是悲剧的 wa(T.T)。。。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 using namespace std; 5 const int inf = 0x3fffffff; 6 const int N = 100005; 7 8 int c[N], in[N], de[N]; 9 10 void output(int *c, int l, int r, const char *s) { 11 puts(""); 12 puts(s); 13 for(int i = l; i <= r; ++i) 14 printf("%d ",c[i]); 15 puts("\n"); 16 } 17 18 int main() { 19 int n; 20 while(~scanf("%d",&n)) { 21 for(int i = 1; i <= n; ++i) 22 scanf("%d", c + i); 23 24 if(n <= 2) { 25 printf("%d\n",n); 26 continue; 27 } 28 29 in[1] = 1; 30 for(int i = 2; i <= n; ++i) { 31 if(c[i - 1] < c[i]) in[i] = in[i - 1] + 1; 32 else in[i] = 1; 33 } 34 35 de[n] = 1; 36 for(int i = n - 1; i >= 1; --i) { 37 if(c[i + 1] > c[i]) de[i] = de[i + 1] + 1; 38 else de[i] = 1; 39 } 40 41 in[n + 1] = de[n + 1] = 0; 42 43 // 如上所说,ans 可以直接初始化为 0,不需要第 1 种情况 44 int ans = max(*max_element(in + 1, in + n + 1), *max_element(de + 1, de + n + 1)); 45 // 下标很重要!!! 46 for(int i = 1; i <= n; ++i) 47 if(c[i - 1] <= c[i + 1] - 2) ans = max(ans, in[i - 1] + de[i + 1] + 1); 48 else ans = max(ans, max(in[i - 1], de[i + 1]) + 1); 49 printf("%d\n",ans); 50 } 51 return 0; 52 }