BZOJ1109: [POI2007]堆积木Klo

来源:互联网 发布:牛贝公众号淘宝客系统 编辑:程序博客网 时间:2024/05/21 17:33

一开始状态就定的不一样…一直想着优化转移然后越走越远..

%%%Seter
我们令f[i]表示第i个积木的积木回到自己的位置,前i个积木最多有多少个归位
枚举前一个归位的积木,可以得到
f[i]=f[j]+1(j<i,a[j]<a[i],ia[i]>=ja[j])
发现像是个三维偏序上的LIS?
但其实不用,可以发现,当a[j]<a[i],ia[i]>=ja[j]同时满足时,一定满足j<i
所以就是求一个很正常的LIS了
ia[i]为第一关键字,a[i]为第二关键字(能保证最长)排序,然后正常做就行了

code:

#include<set>#include<map>#include<deque>#include<queue>#include<stack>#include<cmath>#include<ctime>#include<bitset>#include<string>#include<vector>#include<cstdio>#include<cstdlib>#include<cstring>#include<climits>#include<complex>#include<iostream>#include<algorithm>#define ll long long#define inf 1e9using namespace std;const int maxn = 110000;int n;struct node{    int x,i;}a[maxn];inline bool cmp(const node x,const node y){return x.i-x.x==y.i-y.x?x.x<y.x:x.i-x.x<y.i-y.x;}int t[maxn],tp;int main(){    scanf("%d",&n);    for(int i=1;i<=n;i++) scanf("%d",&a[i].x),a[i].i=i;    sort(a+1,a+n+1,cmp);    for(int i=1;i<=n;i++) if(a[i].i-a[i].x>=0)    {        int now=a[i].x;        if(!tp) { t[tp=1]=a[i].x;continue; }        int l=1,r=tp;        while(l<=r)        {            int mid=l+r>>1;            if(t[mid]<now) l=mid+1;            else r=mid-1;        }++r;        t[r]=now; if(r>tp) tp=r;    }    printf("%d\n",tp);    return 0;}