用f[i]表示前i个数,i必须被贡献的答案,考虑转移,枚举下一个被贡献的数j,那么j需要满足:1.$j<i$;2.$a[j]<a[i]$;3.$a[i]-(i-j+1)\le a[j]$,化简后即$j-a[j]\le i-a[i]$;4.$a[i]\le i$
这是一个三维偏序,但发现第二个限制和第三个限制可以凑出第一个限制,即第一个限制和忽略,按照某一维排序,对另一维求lis即可(注意当$a[i]=a[j]$时要让i-a[i]逆序排序,来保证$a[j]<a[i]$
1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,x,y,a[100005],b[100005],id[100005]; 4 bool cmp(int x,int y){ 5 return (a[x]<a[y])||(a[x]==a[y])&&(x-a[x]>y-a[y]); 6 } 7 int main(){ 8 scanf("%d",&n); 9 for(int i=1;i<=n;i++){ 10 scanf("%d",&a[i]); 11 id[i]=i; 12 } 13 sort(id+1,id+n+1,cmp); 14 for(int i=1;i<=n;i++) 15 if (a[id[i]]<=id[i]){ 16 x=upper_bound(b+1,b+b[0]+1,id[i]-a[id[i]])-b; 17 b[0]=max(b[0],x); 18 b[x]=id[i]-a[id[i]]; 19 } 20 printf("%d",b[0]); 21 }
原文地址:https://www.cnblogs.com/PYWBKTDA/p/12075755.html
时间: 2024-11-06 17:46:38