nyist oj 17 單調遞增最長子序列 (動態規劃經典題)
阿新 • • 發佈:2018-12-24
單調遞增最長子序列
時間限制: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; }