动态规划思路
题目
分析
找子问题
想法1:求序列前n个元素的最长上升子序列的长度
这个子序列中,可能会有多个长度为n的上升子序列,对于一下元素,有些序列的最后一个元素比下一个元素小,有些比下一个元素大,导致问题的解依赖于达到当前状态的路径。不具有无后效性。
想法2:求以元素ak为结尾的最长子序列的长度
由于根据想法1,最后一个元素的值会影响到结果,所以不妨以最后一个元素作为划分,使得问题的无后效性体现出来
状态空间
状态空间是元素的位置 { 1 , 2 , 3 ⋯ N } \{1,2,3\cdots N\} {1,2,3⋯N},其值是以各元素结尾的最长子序列的长度
状态转移方程
F ( k ) = { 1 , k = 1 m a x { F ( i ) ∣ i ∈ [ 1 , k ) a n d a i < a k } , i f ∃ a i < a k , k ≠ 1 1 , i f ∄ a i < a k , k ≠ 1 F(k)= \left\{ \begin{array}{l} 1,k=1\\ max\{F(i)\ |\ i\in[1,k)\ and\ a_i<a_k\},if\exists a_i<a_k,k\not=1\\ 1,if\nexists a_i<a_k,k\not=1 \end{array} \right. F(k)=⎩⎨⎧1,k=1max{F(i) ∣ i∈[1,k) and ai<ak},if∃ai<ak,k=11,if∄ai<ak,k=1
代码
#include<iostream>
#include<fstream>
#define MAXLENGTH 1000
using namespace std;
int Sequence[MAXLENGTH];
int stateValue[MAXLENGTH];
int main(){
int n;
int ptr;
int maxLenSubseqElement;
cin >> n;
for(int cnt=0; cnt<n; cnt++)
scanf("%d", &Sequence[cnt]);
stateValue[0] = 1;
for(int cnt1=1; cnt1<n; cnt1++){
ptr = 0;
maxLenSubseqElement = -1;
for(int cnt2=0; cnt2<cnt1; cnt2++)
if(Sequence[cnt2] < Sequence[cnt1])
if(maxLenSubseqElement == -1 || stateValue[maxLenSubseqElement] < stateValue[cnt2])
maxLenSubseqElement = cnt2;
if(maxLenSubseqElement == -1)
stateValue[cnt1] = 1;
else
stateValue[cnt1] = stateValue[maxLenSubseqElement] + 1;
}
printf("%d", stateValue[n-1]);
return 0;
}