nyist oj 17 单调递增最长子序列 (动态规划经典题)

15 篇文章 0 订阅
2 篇文章 0 订阅

单调递增最长子序列

时间限制: 3000 ms  |  内存限制: 65535 KB
难度: 4
描述
求一个字符串的最长递增子序列的长度
如:dabdbf最长递增子序列就是abdf,长度为4
输入
第一行一个整数0<n<20,表示有n个字符串要处理
随后的n行,每行有一个字符串,该字符串的长度不会超过10000
输出
输出字符串的最长递增子序列的长度
样例输入
3
aaa
ababc
abklmncdefg
样例输出
1
3
7
来源

经典题目

动态规划的经典题目;好像还有好几种解法,我现在研究的是最基础的解法;


这里直接参考了 http://blog.csdn.net/sjf0115/article/details/8715672  的博客,把其中的图片复制过来了,感觉讲的还不错,加深对这类题目的理解;

http://www.cnblogs.com/mycapple/archive/2012/08/22/2651453.html  这篇博客讲的也不错

[cpp]  view plain  copy
  1. #include <cstdio>  
  2. #include <cstring>  
  3. const int maxn=10001;  
  4. char s[maxn];  
  5. int dp[maxn],Max;  
  6. void LICS()  
  7. {  
  8.     int len;  
  9.     memset(dp,0,sizeof(dp));  
  10.     len=strlen(s);  
  11.     for(int i=0;i<len;i++)  
  12.     {  
  13.         dp[i]=1;//给定一个数组求的时候,初始值就是1,一个数组的最大序列肯定会有一个字符;  
  14.         for(int j=0;j<i;j++)  
  15.         {  
  16.             if(s[i]>s[j] && dp[i]<1+dp[j])// 递推公式,如果这个位置比前面的字符都大,就加入到递增序列中来  
  17.                 dp[i]=1+dp[j];  
  18.         }  
  19.     }  
  20.     Max=0;  
  21.     for(int i=0;i<len;i++)//求出最大值  
  22.         if(Max<dp[i])  
  23.           Max=dp[i];  
  24. }  
  25. int main()  
  26. {  
  27.     int t;  
  28.     scanf("%d",&t);  
  29.     while(t--)  
  30.     {  
  31.         scanf("%s",s);  
  32.         LICS();  
  33.         printf("%d\n",Max);  
  34.     }  
  35.     return 0;  
  36. }  

看到了这道题的最优代码;上面我写的提交300多ms,最优代码只要4ms,0ms也许也可以达到;

但是有点看不懂的节奏啊,保存学习一下;

[cpp]  view plain  copy
  1.    
  2.    
  3. #include<iostream>  
  4. #include <string>  
  5. //#include <time.h>  
  6. using namespace std;  
  7. int main()  
  8. {  
  9.     //freopen("1.txt","r",stdin);  
  10.     int n ;  
  11.     cin>>n;  
  12.     while(n--)  
  13.     {  
  14.         string str;  
  15.         int count=1;  
  16.         cin>>str;  
  17.         int a[200];  
  18.         a[0]=-999;  
  19.         for (int i=0;i<str.length();i++)  
  20.         {  
  21.   
  22.             for (int j=count-1;j>=0;j--)  
  23.             {  
  24.                 if((int)str[i]>a[j])  
  25.                 {  
  26.                     a[j+1]=str[i];  
  27.                     if(j+1==count) count++;  
  28.                     break;  
  29.                 }  
  30.             }  
  31.         }  
  32.         cout<<count-1<<endl;  
  33.     }  
  34.     //cout<<(double)clock()/CLOCKS_PER_SEC<<endl;  
  35.     return 0;  
  36. }                  

原文地址:http://blog.csdn.net/whjkm/article/details/38582411

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值