[2016-03-11][最长上升子序列]

[2016-03-11][最长上升子序列]

O(n^2)算法,动态规划,dp[i]表示到第i个位置,最长子序列的长度,那么就有dp[i] = max(dp[i],dp[j] + 1),(j = 1,2,3,...i && a[i] > a[j])
        const int maxn = 1000 + 100;
        int a[maxn],dp[maxn]; 

                 for(int i = 0; i < n ;++i){
                dp[i] = 1;
                for(int j = 0 ; j < i ;++j){
                        if(a[i] > a[j]){
                                dp[i] = max(dp[i],dp[j] + 1);
                        }
                }
        }
        int ans = 0;
        for(int i = 0;i < n;++i){
                ans = max(ans,dp[i]);
        }  

  • nlogn算法
  • 类似贪心,
  • 1.从左边开始往右扫描,每次扫描到一个更大的值,就加入到栈,这个很容易理解
  • 2.每次扫描到比栈顶要小的元素.就替换掉栈内相应位置的元素,这个比较难理解
  • 栈内的元素及其的深度,stk[i] 可以理解为,长度为i + 1的上升子序列中(栈底是从0开始计算,所以是i+1),最小的元素,
      • 第一种情况,新元素比栈顶元素大,直接把新元素入栈,很容易理解
      • 第二种情况,替换栈内元素,
      • 要取最优,那么就应该尽量是每个长度对应的数字应该尽可能小,这样才能在后面遇到一个新的元素的时候,尽可能把更多元素加入到栈中,
      • 比如1 3 6 2 4 5,跟新到1 3 5 之和,遇到2,替换成1 2 5,如果不替换掉3的话,那么后面的4就可能更新到.
       const int maxn = 1000 + 100;
        int a[maxn],stk[maxn];
        int n,pcur = 0;
        for(int i = 0;i < n;++i){
                if(!pcur){
                        stk[pcur++] = a[i];
                }else {
                        if(a[i] > stk[pcur - 1]){
                                stk[pcur++] = a[i];
                        }else if(a[i] < stk[pcur - 1]){
                                int pos = lower_bound(stk,stk + pcur,a[i]) - stk;
                                stk[pos] = a[i];
                        }
                }
        }  





来自为知笔记(Wiz)


posted on 2016-03-11 14:19  红洋  阅读(138)  评论(0)    收藏  举报

导航