码迷,mamicode.com
首页 > 编程语言 > 详细

nyoj 17-单调递增最长子序列(动态规划,演算法)

时间:2018-05-17 23:16:40      阅读:244      评论:0      收藏:0      [点我收藏+]

标签:mes   ane   amp   style   while   name   clear   color   stream   

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-单调递增最长子序列(动态规划,演算法)

标签:mes   ane   amp   style   while   name   clear   color   stream   

原文地址:https://www.cnblogs.com/GetcharZp/p/9053647.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!