nyoj 17-單調遞增最長子序列(動態規劃,演算法)
阿新 • • 發佈:2018-05-18
clear ron queue orange 處理 描述 clas mes math
如:dabdbf最長遞增子序列就是abdf,長度為4
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-單調遞增最長子序列(動態規劃,演算法)