动态规划

【dp笔记】LIS

2018-07-07  本文已影响0人  jenye_

课程笔记:程序设计与算法(二)算法基础:dp


Longest Ordered Subsequence

Time Limit: 2000MS Memory Limit: 65536K
Description
A numeric sequence of ai is ordered if a1 < a2 < ... < aN. Let the subsequence of the given numeric sequence (a1, a2, ..., aN) be any sequence (ai1, ai2, ..., aiK), where 1 <= i1 < i2 < ... < iK <= N. For example, sequence (1, 7, 3, 5, 9, 4, 8) has ordered subsequences, e. g., (1, 7), (3, 4, 8) and many others. All longest ordered subsequences are of length 4, e. g., (1, 3, 5, 8).
Your program, when given the numeric sequence, must find the length of its longest ordered subsequence.
Input
The first line of input file contains the length of sequence N. The second line contains the elements of sequence - N integers in the range from 0 to 10000 each, separated by spaces. 1 <= N <= 1000
Output
Output file must contain a single integer - the length of the longest ordered subsequence of the given sequence.

Sample Input
7
1 7 3 5 9 4 8
Sample Output
4

题目描述

解题步骤

1.找子问题

  1. 确定状态

    • 子问题只和一个变量——数字的位置相关,因此序列中的位置k就是“状态”,而状态k对应的"值",就是以a_k为“终点”的最长上升子序列的长度。
      状态共有N个。
  2. 找出状态转移方程

    • maxLen(x)表示以a_k做为“终点”的最长上升子序列的长度那么:

    初始状态:maxLen(1) = 1
    maxLen(k) = max {maxLen (i) :1<=i<k且a_i<a_k且k\neq1} + 1
    maxLen(k)的值,就是在a_k左边,“终点”数值小于a_k,且上都最大的那个上升子序列的长度再加1。因为a_k左边任何“终点”小于a_k的子序列,加上a_k后就能形成一个更长的上升子序列。

时间时间复杂度:状态的数目*找到状态所花的时间:N个状态*N,所以复杂度为O(n^2)

代码实现

#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN = 100;
int maxLen[MAXN];
int a[MAXN];
int main(){
    int N;
    cin>>N;
    for(int i = 0; i<N ;i++){
        cin>>a[i];
        maxLen[i] = 1;
    }
    for(int i = 1 ;i<N ;i++){
//每次求第a[i]个为终点的lis的长度
        for(int j = 0 ; j<i;j++){
//查看以a[j]为终点的的lis
            if(a[j]<=a[i]){
                maxLen[i] = max(maxLen[i],maxLen[j]+1);
            }
        }
    } //复杂度为O(n*n)
    cout<< * max_element(maxLen,maxLen + N);
    return 0; 
} 

STL之min_element()与max_element


上一篇下一篇

猜你喜欢

热点阅读