最长递增子序列是动态规划中最经典的问题之一,我们从讨论这个问题开始,循序渐进的了解动态规划的相关知识要点。
在一个已知的序列 {a1,a2,...an} 中,取出若干数组成新的序列{ai1,ai2,...aim} , 其中下标i1、i2…im保持递增,即新数列中的各个数之间依旧保持原数列中的 先后顺序,那么我们称新的序列{ai1,ai2,...aim}为原序列的一个子序列。
若在子序 列中,当下标ix>iy 时,aix>aiy ,那么我们称这个子序列为原序列的一个递增 子序列。最长递增子序列问题,就是在一个给定的原序列中,求得其最长递增子 序列长度。
有序列 {a1,a2,...an},我们求其最长递增子序列长度。按照递推求解的思想, 我们用 F[i]代表若递增子序列以
假设,F[1]到 F[
F[x]=max{1,F[j]+1 | x>j && ax>aj}
我们给出求序列{1,4,3,2,6,5}的最长递增子序列长度的所有 F[i]供读者参考:
F[1]=1;
F[2]=max{1, F[1]+1 }=2;
F[3]=max{1, F[j]+1 | aj<a3&&j<3}=max {1,F[1]+1}=2;
………
【求解最长递增子序列代码如下:】
#include<iostream>
using namespace std;
int max(int a,int b)///取最大值函数
{
return a>b?a:b;
}
int main()
{
int list[51],n;
int dp[51];///dp[i]保存以第i个数据结尾的最长递增子序列长度
cin>>n;
for(int i=1;i<=n;i++)//录入序列数据
{
cin>>list[i];
}
for(int i=1;i<=n;i++)//按照数组顺序确定每一个dp[i]
{
int tmax=1;//最大值的初始值为1,即以其结尾的最长递增子序列长度至少为1
//f[i]=max {1, f[j]+1|j<i && list[j]<list[i]}
for(int j=1;j<i;j++)//遍历其前所有数据元素
{
if(list[j]<list[i])//若第j个比当前的值要小
tmax=max(1,dp[j]+1);//将当前元素i排列在j号结尾的最长递增子序列之后,计算其长度dp[j] + 1,若大于当前最大值,则更新最大值
}
dp[i]=tmax;
}
//求出dp的最大值即可
int ans=1;
for(int i=1;i<=n;i++)
{
ans=max(ans,dp[i]);
}
cout<<ans<<endl;
}