本题依然是较为简单的线性dp问题。
原题如下:
![](https://i-blog.csdnimg.cn/blog_migrate/237c341dd8f6b2f51823489b83f6a740.png)
代码如下:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 1e5;
int a[N], f[N];
int res = 0;
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i ++ )
{
cin >> a[i];
f[i] = 1;//初始化递增队列长度为1
}
for(int i = 1; i <= n; i ++ )//枚举每一个数
{
for(int j = 1; j < i; j ++ )//从头寻找递增队列最大值
{
if(a[j] < a[i])
f[i] = max(f[i], f[j] + 1);
}
}
for (int i = 1; i <= n; i ++ )
{
res = max(res, f[i]);
}
cout << res << endl;
}
本题可基于贪心的方法继续优化
设立一个队列,每次若当前值比队尾大时入队,否则替换掉比他大的第一个元素。
原理:当我们进行替换时,队列长度不变,但值变小,更有可能出现更多的递增数。
即原为1 2 5,此时待入队元素为3,我们此时将5替换,队列变为1 2 3,长度不变,但比3大的数数量增加,即为比元素5在队中时更优的方案。
代码如下:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int N = 1e7;
int a[N], f[N];
int res = 0;
vector<int> s;
int main()
{
int n;
cin >> n;
for (int i = 0; i < n; i ++ )
{
cin >> a[i];
f[i] = 1;
}
s.push_back(a[0]);
for (int i = 1; i < n; i ++ )
{
if(a[i] > s.back())
{
s.push_back(a[i]);
}
else
{
*lower_bound(s.begin(), s.end(), a[i]) = a[i];//寻找第一个大于等于a[i]的数并进行替换
}
}
cout << s.size() << endl;
}