单调递增最长子序列(南阳理工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

 

posted @ 2013-07-06 21:54  白来了123  阅读(452)  评论(0编辑  收藏  举报