zoukankan      html  css  js  c++  java
  • 单调递增最长子序列(南阳理工ACM)

    描述

    求一个字符串的最长递增子序列的长度
    如:dabdbf最长递增子序列就是abdf,长度为4

    输入
    第一行一个整数0<n<20,表示有n个字符串要处理
    随后的n行,每行有一个字符串,该字符串的长度不会超过10000
    输出
    输出字符串的最长递增子序列的长度
    样例输入
    3
    aaa
    ababc
    abklmncdefg
    样例输出
    1
    3
    7

    有两种方式可以求解,

    解法一:

          首先对字符串S1进行从小到大排序,然后删除有序数组相同的字符得到S2。再求S1与S2的最长子串即可(求子串的方法见两个字符串的最长相同子序列)。

          排序方法:

     1  public static char[] sort(char[] P,ref int m)
     2         {
     3 
     4             for (int j = 0; j < P.Length - 1; j++)
     5             {
     6                 for (int i = 0; i < P.Length - 1 - j; i++)
     7                 {
     8                     if (P[i] > P[i + 1])
     9                     {
    10                         char point1 = P[i];
    11                         P[i] = P[i + 1];
    12                         P[i + 1] = point1;
    13                     }
    14                 }
    15             }
    16             char x = P[1];
    17             int k = 2;
    18             for (int i = 2; i < P.Length; i++)
    19             {
    20                 if (P[i] != x)
    21                 {
    22                     P[k] = P[i];
    23                     x = P[i];
    24                     k++;
    25                 }
    26             }
    27             m = k;
    28             return P;
    29         }
    View Code

     解法二:

           利用动态规划的思想,求S1[0...i]的最长递增子串,只需要比较S1[0...i-1]中S1[k]与S1[i]的大小。

            f(i)=max(f(i-1),f(i-2),...,f(0))+1;用一个int dp[i]数组保存当前的f(i)值,即到第i个元素的最长递增子序列。

            递推方程的意思是,在求以ai为末元素的最长递增子序列时,找到所有序号在i前面且小于ai的元素aj,即j<i且aj<ai。如果这样的元素存在,那么对所有aj,都有一个以aj为末元素的最长递增子序列的长度f(j),把其中最大的f(j)选出来,那么f(i)就等于最大的f(j)加上1,即以ai为末元素的最长递增子序列,等于以使f(j)最大的那个aj为末元素的递增子序列最末再加上ai;如果这样的元素不存在,那么ai自身构成一个长度为1的以ai为末元素的递增子序列。

     1 public static int LongestAddSubsequence(string A) 
     2         {
     3             int longest = 1;
     4             int[] dp = new int[A.Length];
     5             for (int i = 0; i < A.Length; i++)
     6                 dp[i] = 1;//初始话均为1
     7             for (int i = 1; i < A.Length; i++)
     8                 for (int j = i - 1; j >= 0; j--)
     9                     if (A[i] > A[j] && dp[i] < dp[j] + 1)//遇到比当前值小,并且长度比当前长度大的就更新当前长度
    10                         dp[i] = dp[j] + 1;
    11             for (int i = 0; i < A.Length; i++)
    12                 if (dp[i] > longest)
    13                     longest = dp[i];
    14                 return longest;
    15         }
    View Code
  • 相关阅读:
    23 数字时钟&长图滚动
    22 日期特效&长图滚动
    彻底澄清c/c++指针概念
    已管理员模式运行批处理路径丢失问题的解决方法
    使用mathjax在博客中完美显示数学公式,支持PC,手机浏览器
    GOOGLE高级搜索技巧
    我要搬家
    简单的3proxy配置
    AutoMapper小结
    专业IT培训机构-传智播客
  • 原文地址:https://www.cnblogs.com/xiaoyi115/p/3175549.html
Copyright © 2011-2022 走看看