1. 程式人生 > >nyist oj 17 單調遞增最長子序列 (動態規劃經典題)

nyist oj 17 單調遞增最長子序列 (動態規劃經典題)

單調遞增最長子序列

時間限制:3000 ms  |  記憶體限制:65535 KB 難度:4
描述
求一個字串的最長遞增子序列的長度
如:dabdbf最長遞增子序列就是abdf,長度為4
輸入
第一行一個整數0<n<20,表示有n個字串要處理
隨後的n行,每行有一個字串,該字串的長度不會超過10000
輸出
輸出字串的最長遞增子序列的長度
樣例輸入
3
aaa
ababc
abklmncdefg
樣例輸出
1
3
7
來源

經典題目

動態規劃的經典題目;好像還有好幾種解法,我現在研究的是最基礎的解法;


#include <cstdio>
#include <cstring>
const int maxn=10001;
char s[maxn];
int dp[maxn],Max;
void LICS()
{
    int len;
    memset(dp,0,sizeof(dp));
    len=strlen(s);
    for(int i=0;i<len;i++)
    {
        dp[i]=1;//給定一個數組求的時候,初始值就是1,一個數組的最大序列肯定會有一個字元;
        for(int j=0;j<i;j++)
        {
            if(s[i]>s[j] && dp[i]<1+dp[j])// 遞推公式,如果這個位置比前面的字元都大,就加入到遞增序列中來
                dp[i]=1+dp[j];
        }
    }
    Max=0;
    for(int i=0;i<len;i++)//求出最大值
        if(Max<dp[i])
          Max=dp[i];
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%s",s);
        LICS();
        printf("%d\n",Max);
    }
    return 0;
}

看到了這道題的最優程式碼;上面我寫的提交300多ms,最優程式碼只要4ms,0ms也許也可以達到;

但是有點看不懂的節奏啊,儲存學習一下;

 
 
#include<iostream>
#include <string>
//#include <time.h>
using namespace std;
int main()
{
	//freopen("1.txt","r",stdin);
	int n ;
	cin>>n;
	while(n--)
	{
		string str;
		int count=1;
		cin>>str;
		int a[200];
		a[0]=-999;
		for (int i=0;i<str.length();i++)
		{

			for (int j=count-1;j>=0;j--)
			{
				if((int)str[i]>a[j])
				{
					a[j+1]=str[i];
					if(j+1==count) count++;
					break;
				}
			}
		}
		cout<<count-1<<endl;
	}
	//cout<<(double)clock()/CLOCKS_PER_SEC<<endl;
	return 0;
}