题意:
求最长上升子序列,其中子序列中相邻的两个数的下标差要超过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; }