nyoj 17-单调递增最长子序列(动态规划,演算法)
Posted GetcharZp
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了nyoj 17-单调递增最长子序列(动态规划,演算法)相关的知识,希望对你有一定的参考价值。
17-单调递增最长子序列
内存限制:64MB
时间限制:3000ms
Special Judge: No
accepted:21
submit:49
题目描述:
求一个字符串的最长递增子序列的长度
如:dabdbf最长递增子序列就是abdf,长度为4
如: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-单调递增最长子序列(动态规划,演算法)的主要内容,如果未能解决你的问题,请参考以下文章