BestCoder16 1002.Revenge of LIS II(hdu 5087) 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5087

题目意思:找出第二个最长递增子序列,输出长度。就是说,假如序列为 1 1 2,第二长递增子序列是1 2(下标为2 3),而第一长递增子序列也是(下标为 1 3)。

我一开始天真的以为,还是利用求最长递增子序列的算法啦,第二长不就是对dp 数组sort完后(从小到大)的dp[cnt-1] 啦,接着就呵呵啦~~~~= =

题解说,要加多一个 dp 数组,以便对当前下标值为 i 的数 a[i] 为结尾求出第二条dp序列,如果长度一样就直接那个长度了,否则是长度减 1。一直对每个数这样处理,处理到序列最后一个数就是答案了。

以下是看别人的。设 dp[i][0] 表示以a[i]这个数为结尾的最长递增子序列的长度,dp[i][1] 表示以a[i]这个数为结尾的第二长递增子序列的长度(可能为dp[i][0],也可能是dp[i][0]-1)

然后把每个数的两个dp值放进ans数组中,sort之后,答案就为ans[cnt-2]。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <algorithm>
 6 using namespace std;
 7
 8 const int N = 1000 + 10;
 9
10 int a[N], ans[2*N];
11 int dp[N][2];
12
13 int main()
14 {
15     int T, n;
16     #ifndef ONLINE_JUDGE
17         freopen("input.txt", "r", stdin);
18     #endif
19     while (scanf("%d", &T) != EOF)
20     {
21         while (T--)
22         {
23             scanf("%d", &n);
24             for (int i = 1; i <= n; i++)
25                 scanf("%d", &a[i]);
26             memset(dp, 0, sizeof(dp));
27             int cnt = 0;
28             for (int i = 1; i <= n; i++)
29             {
30                 dp[i][0] = 1;
31                 for (int j = 1; j < i; j++)
32                 {
33                     if (a[j] < a[i])
34                     {
35                         int x = dp[j][0] + 1;
36                         int y = dp[j][1] + 1;
37
38                         if (x > dp[i][0])
39                             swap(x, dp[i][0]);
40                         dp[i][1] = max(x, dp[i][1]);
41                         dp[i][1] = max(y, dp[i][1]);
42                     }
43                 }
44                 ans[cnt++] = dp[i][0];
45                 ans[cnt++] = dp[i][1];
46             }
47             sort(ans, ans+cnt);
48             printf("%d\n", ans[cnt-2]);
49         }
50     }
51     return 0;
52 }
时间: 2024-12-19 20:47:03

BestCoder16 1002.Revenge of LIS II(hdu 5087) 解题报告的相关文章

BestCoder22 1002.NPY and arithmetic progression(hdu 5143) 解题报告

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5143 题目意思:给出 1, 2, 3, 4 的数量,分别为a1, a2, a3, a4,问是否在每个数只使用一次的前提下,分成若干部分,每部分数的长度 >= 3且满足是等差数列.可以的话输出 Yes ,否则 No . 比赛的时候过了pretest,那个开心啊--然后跟 XX 兽讨论了之后,才发现自己理解错了题目= = 要用到深搜,问组合嘛--组合就是有可能是(1, 2, 3, 4).(1, 2, 3

hdu 5087 Revenge of LIS II(LIS)

题目连接:hdu 5087 Revenge of LIS II 题目大意:给定一个序列,求第2长的LIS长度. 解题思路:用o(n^2)的算法求LIS,每个位置维护两个值,最大和最小即可.注意的是dp[0]中的最大第二大不能都复制成0. #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn = 1005; int N, A[maxn],

HDU 5087 Revenge of LIS II(次长上升子序列)

题意  求一个序列的所有上升子序列中第二长的那个的长度 简单的dp   d[i]表示以第i个数结尾的最长上升子序列的长度  c[i]表示到达d[i]的方法数  如序列1 1 2  d[3]=2,c[3]=2  因为选1 3位置和 2 3位置的都可以得到d[3]=2 递推过程很简单 d[i]=max{d[j]+1}其中a[i]>a[j]&&i>j 最后看d[1~n]中最大的数出现了几次  出现了不止一次就直接输出否则就减一输出咯 #include <cstdio> #

hdu 5087 Revenge of LIS II lcs变形

点击打开链接链接 Revenge of LIS II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1028    Accepted Submission(s): 334 Problem Description In computer science, the longest increasing subsequence proble

hdu 5087 Revenge of LIS II(BestCoder Round #16)

Revenge of LIS II                                                  Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 528    Accepted Submission(s): 173 Problem Description In computer science, th

HDU 5087 Revenge of LIS II(次大递增子序列)

Revenge of LIS II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1258    Accepted Submission(s): 423 Problem Description In computer science, the longest increasing subsequence problem is to f

hdoj 5087 Revenge of LIS II 【第二长单调递增子】

称号:hdoj 5087 Revenge of LIS II 题意:非常easy,给你一个序列,让你求第二长单调递增子序列. 分析:事实上非常easy.不知道比赛的时候为什么那么多了判掉了. 我们用O(n^2)的时间求单调递增子序列的时候,里面在加一层循环维护sum数组.表示前面有几个能够转移当当前,求前面sum的和保存到当前. 最后求最后一个sum[n-1]是否为1就ok.为1的话在最长的基础上减一,否则就是最长的. AC代码: #include <iostream> #include &l

hdoj 5087 Revenge of LIS II 【第二长单调递增子序列】

题目:hdoj 5087 Revenge of LIS II 题意:很简单,给你一个序列,让你求第二长单调递增子序列. 分析:其实很简单,不知道比赛的时候为什么那么多了判掉了. 我们用O(n^2)的时间求单调递增子序列的时候,里面在加一层循环维护sum数组,表示前面有几个可以转移当当前,求前面sum的和保存到当前. 最后求最后一个sum[n-1]是否为1就ok,为1的话在最长的基础上减一,否则就是最长的. AC代码: #include <iostream> #include <algor

HDOJ 5087 Revenge of LIS II DP

DP的时候记录下是否可以从两个位置转移过来.... Revenge of LIS II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 393    Accepted Submission(s): 116 Problem Description In computer science, the longest increasing su