最长上升子序列

Description

求最长上升子序列。

Input

单测试用例。

第一行是一个正整数n,0 < n ≤ 3000

第二行是n个非负整数。

Output

两行结果。

第一行是最长上升子序列的长度。

第二行是任意一个最长上升子序列,每个整数后面跟一个空格。

Sample Input

8
5 2 8 6 3 6 9 7

Sample Output

4
2 3 6 7

AC代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn = 3e3 + 10;
int n, len, en, squ[maxn], dp[maxn], pre[maxn];
 void so()
{
    len = en = 1;
    dp[1] = 1;
    for(int i=2; i<=n; i++){
        dp[i] = 1;
        for(int j=1; j<i; j++){

            if(squ[j] < squ[i] && dp[j]+1 > dp[i]){
                dp[i] = dp[j]+1;
                pre[i] = j;
            }
        }
        if(dp[i] > len){
            len = dp[i];
            en = i;
        }
    }
}
int main(void)
{
    scanf("%d", &n);
    for(int i=1; i<=n; i++){
        scanf("%d", &squ[i]);
        pre[i] = i;
    }
    so();
    printf("%d\n", len);
    stack<int> res;
    while(pre[en] != en){
        res.push(squ[en]);
        en = pre[en];
    }
    printf("%d ", squ[en]);
    while(!res.empty()){
        printf("%d ", res.top());
        res.pop();
    }puts("");
    return 0;
}
View Code

 

 

求一个序列中每次都删除最长的单调序列,要进行多少轮

#include<bits/stdc++.h>

using namespace std;

int main(){

int i=1,ans=-1,s=-1,a[1010],dp[1010],sys[1010];

while(cin>>a[i]){

dp[i]=sys[i]=1;

for(int j=i-1;j>=1;j--)

if (a[j]>=a[i]) dp[i]=max(dp[j]+1,dp[i]);

else if (a[j]<a[i]) sys[i]=max(sys[j]+1,sys[i]);

ans=max(ans,dp[i]);

s=max(s,sys[i]);

i++;

}

cout<<ans<<endl<<s<<endl;;

return 0;

}
View Code

S是答案

posted @ 2018-05-15 21:42  shuai_hui  阅读(136)  评论(0编辑  收藏  举报