码迷,mamicode.com
首页 > 其他好文 > 详细

[bzoj1109]堆积木

时间:2019-12-21 10:05:47      阅读:69      评论:0      收藏:0      [点我收藏+]

标签:bool   sort   show   必须   i++   忽略   name   答案   splay   

用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 }
View Code

[bzoj1109]堆积木

标签:bool   sort   show   必须   i++   忽略   name   答案   splay   

原文地址:https://www.cnblogs.com/PYWBKTDA/p/12075755.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!