今天,刷了一道上升子序列的题ACwing896,这题的思路不同于以往的上升子序列的题,如果使用dp很容易超时,权衡之下应当选择贪心策略。
题面:
给定一个长度为 NN 的数列,求数值严格单调递增的子序列的长度最长是多少。
输入格式
第一行包含整数 N。
第二行包含 N 个整数,表示完整序列。
输出格式
输出一个整数,表示最大长度。
数据范围
1≤N≤100000,
−1e9≤数列中的数≤1e9
输入样例:
7
3 1 2 1 8 5 6
输出样例:
4
#include <bits/stdc++.h>
using namespace std;
#define sin scanf
#define sout printf
#define ll long long
#define PII pair<int,int>
const int INF=0x3f3f3f3f;
const int Mod=1e9+7;
const int maxn = 1e6+10;
#define MY_LOCAL
int main()
{
ios::sync_with_stdio(false);
cin.tie(0),cout.tie(0);
#ifdef MY_LOCA
freopen("E:/wolf/c++/solutions/input.txt","r",stdin);
#endif
int n;
cin>>n;
vector<int>arr(n+1);
for(int i=1;i<=n;i++)
{
cin>>arr[i];
}
vector<int>stk;
stk.push_back(arr[1]);
for(int i=2;i<=n;i++)
{
if(arr[i]>stk.back())
{
stk.push_back(arr[i]);
}
else
{
*lower_bound(stk.begin(),stk.end(),arr[i])=arr[i];//这个地址对应的值是它
}
}
cout<<stk.size()<<endl;
return 0;
}
其中 *lower_bound(arr.begin(),arr.end(),arr[i])=arr[i];一句让我受益匪浅,lower_bound()函数返回得到答案的地址,加*取其地址,并使这个地址的值变为arr[i],如果只有这个函数我们可以只使用一个角标来替代,进而通过类似arr[cnt]=arr[i]来达到同样地效果。