Approximating a Constant Range CodeForces

来源:互联网 发布:全国淘宝店铺有多少个 编辑:程序博客网 时间:2024/05/21 09:01

想了很久想不出怎么用 尺取法做。。

题意:给定一个由n个元素组成的序列a[],保证相邻元素之间差的绝对值不超过1。问你最长的T序列。

看了别人的dp,好好啊。
http://blog.csdn.net/gungnir0711/article/details/50280247
也看到有用单调队列+尺取法的

也可以用队列做吧。。

int main(){        int n;        scanf("%d",&n);        int ans=0;        for(  int i=1; i<=n; i++ )        {              int x;              scanf( "%d",&x );              if(  dp[x-1]>dp[x+1] ) ans=max(  ans,i-max(  dp[x-2],dp[x+1] )  );              else ans=max(  ans, i-max(dp[x+2],dp[x-1] ) );              dp[x]=i;        }        printf( "%d\n",ans );        return 0;}

学了下师兄弟的 st+ 二分

int a[mxn];int mini[mxn][20],maxi[mxn][20];int n;int mm[mxn];void initmin(int n){    mm[0]=-1;    for(int i=1;i<=n;++i){        mini[i][0]=a[i];        mm[i]=((i&(i-1))==0)?mm[i-1]+1:mm[i-1];    }    int k=mm[n];    for(int j=1;j<=k;++j)        for(int i=1;i+( 1<<j)-1<=n;++i)            mini[i][j]=min(mini[i][j-1],mini[i+(1<<(j-1))][j-1]);}int getmin(int x,int y){    int k=mm[y-x+1];    return min(mini[x][k],mini[y-(1<<k)+1][k]);}void initmax(int n){    mm[0]=-1;    for(int i=1;i<=n;++i){        maxi[i][0]=a[i];        mm[i]=((i&(i-1))==0)?mm[i-1]+1:mm[i-1];    }    int k=mm[n];    for(int j=1;j<=k;++j)        for(int i=1;i+(1<<j)-1<=n;++i)            maxi[i][j]=max(maxi[i][j-1],maxi[i+(1<<(j-1))][j-1]);}int getmax(int x,int y){    int k=mm[y-x+1];    return max(maxi[x][k],maxi[y-(1<<k)+1][k]);}bool judge(int len){    for(int i=1;i+len-1<=n;++i){        if(getmax(i,i+len-1)<=getmin(i,i+len-1)+1)return true;    }    return false;}int main(){    sf("%d",&n);    rep(i,1,n)sf("%d",&a[i]);    initmin(n);    initmax(n);    int lb=1,ub=n+1;    int mid;    while(ub-lb>1){        mid=(lb+ub)>>1;        if(judge(mid))lb=mid;        else ub=mid;    }    pf("%d\n",lb);}
原创粉丝点击