动态规划 最长上升子序列 LIS

动态规划 最长上升子序列 LIS-

(1) O(n^2) 动态规划

(2) O(nlogn) 二分做法

(1) 动态规划做法:

#include <iostream>
#include <cstring>
using namespace std;
int dp[101],a[101],n;
int LIS(){
    int ans = 0;
    for(int i=1;i<=n;i++){
        dp[i] = 1;
        for(int j=1;j<i;j++){
            if(a[j] < a[i]){
                dp[i] = max(dp[i],dp[j] + 1);
            } 
        }
        ans = max(ans,dp[i]);
    }
    return ans;
}
int main() {
    cin >> n;
    for(int i=1;i<=n;i++){
        cin >> a[i];
    }
    cout << LIS() << endl;
    return 0;
}

(2) 二分搜索

#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 1e4;
int a[MAXN];
int d[MAXN]; 
const int INF = 0x3f3f3f3f;
int main(){
    ios::sync_with_stdio(false);
    int n;
    while(cin >> n && n){
        int cnt = 0;
        d[0] = 0;//哨兵 
        for(int i=0;i<n;++i){
            cin >> a[i];
            if(d[cnt] < a[i]){
                d[++cnt] = a[i];
            }else{
                int pos = upper_bound(d,d+cnt,a[i]) - d;
                d[pos] = a[i];
            }
        }
        cout << cnt << endl;        
    }
    return 0;
}

题目:

  HDU1087

题解:

#include <iostream>
#include <algorithm>
using namespace std;
int a[1001];
int dp    [1001]; 
const int INF = 0x3f3f3f3f;
int main(){
    int n;
    while(cin >> n&& n){
        for(int i=0;i<n;++i){
            cin >> a[i];
        }
        for(int i=0;i<n;++i){
            dp[i] = a[i];
            for(int j=0;j<i;++j){
                if(a[i] > a[j]){
                    dp[i] = max(dp[j] + a[i],dp[i]);
                }
            }
        }
        int maxN = a[0];
        for(int i=0;i<n;++i){
            maxN = max(maxN,dp[i]);
        }
        cout << maxN << endl;
    }

    return 0;
}
View Code
原文地址:https://www.cnblogs.com/--zz/p/10568179.html