1. 程式人生 > >nyoj 17-單調遞增最長子序列(動態規劃,演算法)

nyoj 17-單調遞增最長子序列(動態規劃,演算法)

clear ron queue orange 處理 描述 clas mes math

17-單調遞增最長子序列


內存限制:64MB 時間限制:3000ms Special Judge: No
accepted:21 submit:49

題目描述:

求一個字符串的最長遞增子序列的長度
如:dabdbf最長遞增子序列就是abdf,長度為4

輸入描述:

第一行一個整數0<n<20,表示有n個字符串要處理
隨後的n行,每行有一個字符串,該字符串的長度不會超過10000

輸出描述:

輸出字符串的最長遞增子序列的長度

樣例輸入:

3
aaa
ababc
abklmncdefg

樣例輸出:

1
3
7

分析(動態規劃):
  ①、要求整體的最大長度,我們可以從局部的最大長度來考慮;
  ②、從左到右依次考慮,每遇到一個點就從第一位開始遍歷到該點,看以這個點作為前綴是否為最大值
  ③、狀態方程:dp[i] = max(dp[i], d[j] + 1);

步驟:
  ①、從左到右依次遍歷每一個點;
  ②、在該點基礎上再從前到後通過 dp[i] = max(dp[i], d[j] + 1) 得出該點最大的值

核心代碼:
1 for(int i = 0; i < n; ++ i)
2 {
3     dp[i] = 1; //初始化每個dp[MAXN];
4     for(int j = 0; j < i; ++ j)
5         if(s[j] < s[i]) dp[i] = max(dp[i], dp[j] + 1); //找出所有滿足條件的s[j] ==> dp[i]最大值
6     ans = max(ans, dp[i]);
7 }

C/C++代碼實現(AC):

 1 #include <iostream>
 2 #include <algorithm>
 3
#include <cmath> 4 #include <cstring> 5 #include <cstdio> 6 #include <queue> 7 #include <set> 8 #include <map> 9 #include <stack> 10 11 using namespace std; 12 const int MAXN = 10010; 13 14 int main () 15 { 16 int t; 17 scanf("%d", &t); 18 while(t --) 19 { 20 char s[MAXN]; 21 scanf("%s", s); 22 int len = strlen(s), ans = -0x3f3f3f3f, dp[MAXN]; 23 for(int i = 0; i < len; ++ i) 24 { 25 dp[i] = 1; 26 for(int j = 0; j < i; ++ j) 27 if (s[j] < s[i]) 28 dp[i] = max(dp[i], dp[j] + 1); 29 ans = max(ans, dp[i]); 30 } 31 printf("%d\n", ans); 32 } 33 return 0; 34 }

※分析(演算法)【推薦】:
  ①、找出醬紫的序列:從左到右的排列是由ASCⅡ碼遞增;
  ②、且每一組相鄰的點ASCⅡ之差最小,及就是最為接近

核心代碼:
 1 cnt = 0; temp[0] = s[0];
 2 for(int i = 1; i < n; ++ i)
 3 {
 4     if(temp[cnt] < s[i]) temp[++cnt] = s[i] // cnt + 1即為所求
 5     else
 6     {
 7         for(int j = 0; j <= cnt; ++ j)
 8         {
 9             if(s[i] <= temp[j])
10             {
11                 temp[j] = s[i];
12                 break;
13             }
14         }
15     }
16 }

C/C++代碼實現(AC):

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cmath>
 4 #include <cstring>
 5 #include <cstdio>
 6 #include <queue>
 7 #include <set>
 8 #include <map>
 9 #include <stack>
10 
11 using namespace std;
12 const int MAXN = 10010;
13 
14 int main ()
15 {
16     int t;
17     scanf("%d", &t);
18     while(t --)
19     {
20         char s[MAXN], temp[MAXN];
21         scanf("%s", s);
22 
23         int len = strlen(s), cnt = 0;
24         temp[0] = s[0];
25         for(int i = 1; i < len; ++ i)
26         {
27             if(temp[cnt] < s[i])
28             {
29                 temp[++cnt] = s[i];
30                 continue;
31             }
32 
33             for(int j = 0; j <= cnt; ++ j)
34             {
35                 if(s[i] <= temp[j])
36                 {
37                     temp[j] = s[i];
38                     break;
39                 }
40             }
41         }
42         printf("%d\n", cnt + 1);
43     }
44     return 0;
45 }

nyoj 17-單調遞增最長子序列(動態規劃,演算法)