Offer 驾到,掘友接招!我正在参与2022春招打卡活动,点击查看活动详情。
题目描述
给定一个长度为 N 的数列,求数值严格单调递增的子序列的长度最长是多少。
输入格式
第一行包含整数 N。
第二行包含 N 个整数,表示完整序列。
输出格式
输出一个整数,表示最大长度。
数据范围
1≤N≤10001≤N≤1000, −109≤数列中的数≤109
输入样例:
7
3 1 2 1 8 5 6
复制代码
输出样例:
4
复制代码
思路
通过题目我们可以很容易发现,这是一道动态规划的题目,在这里我们可以把它细分成线性DP问题。针对此类问题我们还是采用解决动态规划的一般思路,即从题目抽象出状态表示,再用具体的状态计算得出我们想要的结果。
状态表示:用f[i]数组表示一个集合:所有以第i个数结尾的上升子序列,其每个元素就具有一个属性MAX(上升子序列的最长长度)
状态计算:f[i] = max(f[j] + 1)
,j = 0, 1, 2, …., i – 1
代码
#include <iostream>
using namespace std;
const int N = 10010;
int a[N], q[N];
int main()
{
int n;
cin >> n;
for(int i = 1;i <= n;i ++ ) cin >> a[i];
for(int i = 1;i <= n;i ++)
{
q[i] = 1;// 刚开始只有自己本身一个数字
for(int j = 1;j < i;j ++)
{
// 如果符合条件 ,进行更新
if(a[j] < a[i]) q[i] = max(q[i],q[j] + 1);
}
}
int ans;
for(int i = 1;i <= n;i ++) ans =max(ans, q[i]);
cout << ans << endl;
}
复制代码
总结
针对此类动态规划问题,我们都可以从两个层面去思考,即状态表示和状态计算。在我们明确状态所代表的含以后,可以很清楚的理清整个题目的脉络。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END