zoukankan      html  css  js  c++  java
  • [BZOJ]1109: [POI2007]堆积木Klo

    题解:    我们考虑第j个位置从第i个位置的转移

        $$ i< j $$

        $$ a[i]< a[j] $$

        $$ i-a[i]leqslant j-a[j] $$

    看上去是个三维偏序  然后实质上满足2,3式 1式恒成立  然后就是二维偏序问题 我们考虑 直接对a数组排序 然后线段树做转移(当然树状数组也是可以的

    #include <algorithm>
    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <vector>
    #include <stack>
    #include <queue>
    #include <cmath>
    #include <set>
    #include <map>
    #define mp make_pair
    #define pb push_back
    #define pii pair<int,int>
    #define link(x) for(edge *j=h[x];j;j=j->next)
    #define inc(i,l,r) for(int i=l;i<=r;i++)
    #define dec(i,r,l) for(int i=r;i>=l;i--)
    const int MAXN=3e5+10;
    const double eps=1e-8;
    #define ll long long
    using namespace std;
    struct edge{int t,v;edge*next;}e[MAXN<<1],*h[MAXN],*o=e;
    void add(int x,int y,int vul){o->t=y;o->v=vul;o->next=h[x];h[x]=o++;}
    ll read(){
        ll x=0,f=1;char ch=getchar();
        while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
        while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
        return x*f;
    }
    
    
    int dp[MAXN],maxx[MAXN<<2];
    int a[MAXN];
    
    vector<int>vec;
    
    void update(int rt,int l,int r,int t,int k){
        maxx[rt]=max(maxx[rt],k);
        if(l==r)return ;
        int mid=(l+r)>>1;
        if(t<=mid)update(rt<<1,l,mid,t,k);
        else update(rt<<1|1,mid+1,r,t,k);
    }
    
    int ans;
    void query(int rt,int l,int r,int ql,int qr){
        if(ql>qr)return ;
        if(ql<=l&&r<=qr){ans=max(ans,maxx[rt]);return ;}
        int mid=(l+r)>>1;
        if(ql<=mid)query(rt<<1,l,mid,ql,qr);
        if(qr>mid)query(rt<<1|1,mid+1,r,ql,qr);
    }
    
    vector<int>v[1000006];
    
    int main(){
        int n=read();
        int T=0;
        inc(i,1,n)a[i]=read(),v[a[i]].pb(i),T=max(T,a[i]),vec.pb(i-a[i]);
        sort(vec.begin(),vec.end());
        int base=unique(vec.begin(),vec.end())-vec.begin();
        int Maxx=0;
        for(int i=1;i<=T;i++){
        if(v[i].size()==0)continue;
        for(int j=0;j<v[i].size();j++){
            if(v[i][j]-i<0){dp[v[i][j]]=0;continue;}
            int t=lower_bound(vec.begin(),vec.begin()+base,v[i][j]-i)-vec.begin()+1;
            ans=0;query(1,1,base,1,t);
            dp[v[i][j]]=max(1,ans+1);
            Maxx=max(Maxx,dp[v[i][j]]);
        }
        for(int j=0;j<v[i].size();j++){
            if(v[i][j]-i<0){continue;}
            int t=lower_bound(vec.begin(),vec.begin()+base,v[i][j]-i)-vec.begin()+1;
            update(1,1,base,t,dp[v[i][j]]);
        }
        }
        printf("%d
    ",Maxx);
        return 0;
    }
    

      

    1109: [POI2007]堆积木Klo

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 1346  Solved: 506
    [Submit][Status][Discuss]

    Description

      Mary在她的生日礼物中有一些积木。那些积木都是相同大小的立方体。每个积木上面都有一个数。Mary用他的
    所有积木垒了一个高塔。妈妈告诉Mary游戏的目的是建一个塔,使得最多的积木在正确的位置。一个上面写有数i
    的积木的正确位置是这个塔从下往上数第i个位置。Mary决定从现有的高塔中移走一些,使得有最多的积木在正确
    的位置。请你告诉Mary她应该移走哪些积木。

    Input

      第一行为一个数n,表示高塔的初始高度。第二行包含n个数a1,a2,...,an,表示从下到上每个积木上面的数。
    (1<=n<=100000,1<=ai<=1000000)。

    Output

      注意:请输出最多有多少点可以处在正确位置

    Sample Input

    5
    1 1 2 5 4

    Sample Output

    3

     

  • 相关阅读:
    java类加载机制
    java反射
    java注解
    设计模式 单例模式
    #1015 : KMP算法
    idea 快捷键
    基础数据类型综合
    工厂模式 VS 策略模式
    AtomicI 多线程中的原子操作
    ThreadLocal<T>
  • 原文地址:https://www.cnblogs.com/wang9897/p/10355249.html
Copyright © 2011-2022 走看看