• 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
    ", ans[cnt-2]);
    49         }
    50     }
    51     return 0;
    52 }
  • 相关阅读:
    929. 独特的电子邮件地址
    [工具.tcp]测试TCP通讯的网络延迟
    [技巧.Dotnet]轻松实现“强制.net程序以管理员身份运行”。
    [问题记录.VisualStudio]VS2013无法新增和打开项目
    [问题记录.VisualStudio]TFS项目映射问题解决
    [问题记录.dotnet]取网卡信息报错"找不到"-WMI
    模型驱动的数学原理
    剑指OFFER 旋转数组的最小数字
    剑指OFFER 用两个栈实现队列
    剑指OFFER 按之字形顺序打印二叉树
  • 原文地址:https://www.cnblogs.com/windysai/p/4075008.html
Copyright © 2020-2023  润新知