题目来自洛谷P3637,有改动。
实在没啥难点的题了,就水写一下
当年A的第一道线性DP。
题目描述
这是一个简单的动规板子题。
给出一个由 n(n≤5000) 个不超过 106 的正整数组成的序列。请输出这个序列的最长上升子序列的长度。
最长上升子序列是指,从原序列中按顺序取出一些数字排在一起,这些数字是逐渐增大的。
输入格式
第一行,一个整数 n,表示序列长度。
第二行有 n 个整数,表示这个序列。
输出格式
一个整数表示答案。
输入输出样例
输入 #1复制
6 1 2 4 1 3 4
输出 #1复制
4
说明/提示
分别取出 1、2、3、4即可。
106的数据范围,枚举都能过,而且应该没人不会。
但是,只讲DP。
没啥好讲的。
f[i]表示以f[i]结尾的最长上升子序列,初始为1
对于每一个f[i],枚举前面是否有比它小的a[j],如果有,更新f[i]的值。
状态转移方程F[i]=max(F[i],F[j+1])
STD:
#include<bits/stdc++.h>
using namespace std;
int a[5005],f[5005];
int main()
{
int n,ans=0;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
f[i]=1;
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=i-1;j++)
{
if(a[j]<=a[i])
{
f[i]=max(f[i],f[j]+1); //状态转移
}
}
}
for(int i=1;i<=n;i++) //找最大值
{
ans=max(ans,f[i]);
}
cout<<ans;
return 0;
}