Poj百练 2533:Longest Ordered Subsequence(分类:动态规划)

这道题可以说是动态规划问题的一道经典的不能再经典的题目,请反复琢磨理解,这道题太重要了!

我们来分析一下,按照动态规划问题的一般解题思路。

第一步,寻找子问题。猛一看可以想到的子问题大概有两个1.maxLen[i]:以i结尾的最长子序列长度     2.maxLen[i][j]以i开始j结尾的最长子序列的长度。   

首先来看第一种方法,很合适,没有问题。再看第二种方法,举个例子,从i到j的长度肯定大于等于i+1到j的长度,所以这种方法产生了大量的空间冗余(二维数组),而且不确定是否正确,我们放弃。

第二步,寻找状态转移方程,这是个硬功夫,而且这道题的方程还有一些特殊。

仔细想一下后项i和前项j(1<=j<i)会有什么联系呢?大概有两种可能,1.num[i]比num[j]大,符合要求2.num[i]比num[j]小,不符合要求,直接舍弃。而当.num[i]比num[j]大时,我们又需要从i之前的所有数中挨个来尝试,寻找最大的。

于是可以得到状态转移方程

okay! coding.

#include<cstdio>
#include<iostream>
using namespace std;

int n;
int main(){
    cin >> n;
    //num为输入的数组,maxLen为子问题:以i为结尾的最长上升子序列
    int num[n+5], maxLen[n+5];
    for(int i = 1; i <= n; i++)
        cin >> num[i];

    maxLen[1] = 1;
    //根据状态转移方程有如下
    for(int i = 2; i <= n; i++){
            int max = 0;
        for(int j = 1; j < i; j++){
            if(num[i] > num[j] && maxLen[j] > max)
                max = maxLen[j];
            }
        maxLen[i] = max + 1;
    }

    从maxLen找到并输出最大的就是答案
    int ans = 0;
    for(int i = 1; i <= n; i++){
        if(maxLen[i] > ans)
            ans = maxLen[i];
    }

    cout << ans;
}

猜你喜欢

转载自blog.csdn.net/a1097304791/article/details/81219918
今日推荐