题意:
求最长上升子序列,其中子序列中相邻的两个数的下标差要超过k
题解:
英语不好读题都读不好 之前看成了子序列中相邻的两个数的大小要超过k怎么都做不对
后来lower_bound写成了upper_bound
记住了最长上升子序列如果要求严格上升的话就是lower_bound 可以相等的话就是upper_bound
子序列中相邻的两个数的下标要超过k,要想满足这个条件我们可以按下面的思路想:
首先nlogn的LIS是毫无疑问的,然后再这个算法中,我们每次二分找到当前数的位置,如果数组中的数比当前数大的话就更新数组
所以我们可以稍微改一下上述步骤,当我们二分计算当前数的位置时,只是把当前数应该在数组中的位置保存下来,当前只更新在i-k之前的那个数,
这样我们就可以保证每次二分查找时,数组中的所有数的下标都比当前的下标少至少k
质体还有的解法是线段树 我没怎么考虑 有兴趣可以去看看
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
const int N=1e5+10;
int d[N],a[N],b[N];
int main()
{//freopen("C:\\Users\\Administrator\\Desktop\\input.txt","r",stdin);
int n,i,r,k;
while(scanf("%d%d",&n,&k)!=EOF){
for(i=0;i<=n;i++)d[i]=inf;
for(i=0;i<n;i++)scanf("%d",&a[i]);
r=0;
for(i=0;i<n;i++){
int x=lower_bound(d,d+r,a[i])-d;
b[i]=x;
if(x==r) r++;
int j=i-k;
if(j>=0&&d[b[j]]>a[j])d[b[j]]=a[j];
}
printf("%d\n",r);
}
return 0;
}