poj 2533 关于最长上升子序列的问题

以poj 2533为例

dp里面的经典问题 最长上升子序列

经典的方法, d[i]表示以第i个数结尾的最长上升子序列长度

d[j] = max{d[i] + 1 | i < j } 最终答案为d[j]中的最大值, 从小到大扫描即可完成, 一共两重循环

复杂度为O(n^2)

 

复杂度更低的优化的方法, d[i]数组不变, 增加一个新的数组c[i],表示长度为i的上升子序列的结尾的数的值

许多文章当中都有针对这个问题的证明: 对于寻找以某个数结尾的上升子序列, 那么这儿数之前的长度相同的子序列, 更优化的选择

是选择位置靠前的。

例如两个状态 d[a] = d[b]   a < b, 对于后续的选择 d[a] 要比 d[b] 更有优势

所以对于长度相同(即d[]相同)的序列, 都取靠近左侧的值即可

外面的循环不变,内部循环采用二分查找的方法直接找到对于A[i]合适的C[j], 更新d的数值和C[j]的数值, 这里使用STL的lower_bound会更为简洁

 

poj 2533

 两种不同方法的实现, 不同之处主要在于内部的循环, 前者为n此遍历, 后者为二分查找logn

#include <iostream>
#include <vector>
#include <map>
#include <list>
#include <set>
#include <deque>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#include <cctype>
#include <cstdio>
#include <iomanip>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <string>
#include <sstream>
#include <cstring>
#include <queue>
using namespace std;

///宏定义
const int  INF = 990000000;
const int MAXN = 100010;
const int maxn = MAXN;
///全局变量 和 函数

int n;
int A[maxn];
int d[maxn]; //dp中以第i个数结尾的最长上升序列的数值
int c[maxn]; //最长上升序列长度为i的最后一个结尾数的数值
int ans;
int main()
{
    ///变量定义
    while (scanf("%d", &n) != EOF)
    {
        for (int i = 0; i < n; i++)
        {
            scanf("%d", &A[i]);
            d[i] = 1;
        }
        ans = 1;
        
        //o(n^2)的方法
        /*
        for (int i = 1; i < n; i++)
        {
            for (int j = 0; j < i; j++)
            {
                if (A[i] > A[j])
                {
                    d[i] = max(d[i], d[j] + 1);
                }
            }
        }
        */
        //o(nlgn)的方法
        //初始化C数组
        for (int i = 0; i <= n; i++)
            c[i] = INF;

        for (int i = 0; i < n; i++)
        {
            int k = lower_bound(c + 1, c + n + 1, A[i]) - c;
            d[i] = k;
            c[k] = A[i];
        }

        for (int i = 0; i < n; i++)
            ans = max(ans, d[i]);
        printf("%d\n", ans);
    }

    ///结束
    return 0;
}

 

 

 

posted on 2013-11-14 10:37  小书包_Ray  阅读(214)  评论(0编辑  收藏  举报

导航