zoukankan      html  css  js  c++  java
  • BZOJ 1109 [POI2007]堆积木Klo(树状数组)

    【题目链接】 http://www.lydsy.com/JudgeOnline/problem.php?id=1109

    【题目大意】

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

    【题解】

      我们发现我们需要找到这样序列,i是递增的,a[i]也是递增的,
      i-a[i]是非严格递增的,因为i=a[i]+(i-a[i]),
      因此第一个递增条件是后面两个条件的必要不充分条件,
      这样就是一个二维的LIS,我们按照其中一维排序,用树状数组维护另一维即可。

    【代码】

    #include <cstdio>
    #include <algorithm>
    #include <cstring> 
    using namespace std;
    const int N=100010;
    struct data{int x,y;}p[N];
    int c[N],n,x,cnt;
    bool cmp(data a,data b){
    	if(a.x!=b.x)return a.x<b.x;
    	else return a.y<b.y;
    }
    void add(int x,int val){while(x<=n)c[x]=max(c[x],val),x+=x&-x;}
    int query(int x){int s=0;while(x)s=max(s,c[x]),x-=x&-x;return s;}
    int main(){
        while(~scanf("%d",&n)){
            int ans=cnt=0;
            memset(c,0,sizeof(c));
            for(int i=1;i<=n;i++){
                scanf("%d",&x);
                if(i-x>=0){p[cnt++]={i-x,x};}
            }sort(p,p+cnt,cmp);
            for(int i=0;i<cnt;i++){
            	int tmp=query(p[i].y-1)+1;
            	ans=max(ans,tmp);
            	add(p[i].y,tmp);
            }printf("%d
    ",ans);
        }return 0;
    }
  • 相关阅读:
    求职简历撰写要点和模板分享
    find命令
    MD5Init-MD5Update-MD5Final
    Linux find命令详解
    Linux进程KILL不掉的原因
    Linux操作系统的内存使用方法详细解析
    Lsof命令详解
    为什么ps中CPU占用率会有超出%100的现象?
    第12课 经典问题解析一
    第11课 新型的类型转换
  • 原文地址:https://www.cnblogs.com/forever97/p/bzoj1109.html
Copyright © 2011-2022 走看看