zoukankan      html  css  js  c++  java
  • 九度OJ 1344:可乐瓶展览 (DP)

    时间限制:1 秒

    内存限制:32 兆

    特殊判题:

    提交:430

    解决:76

    题目描述:
    众所周知JOBDU旗下的JOBCOLA公司是文明全球的著名可乐制造商,与其它可乐公司不同的是,JOBCOLA可乐公司并不是以其可乐的味道闻名,而是以其不同寻常的包装瓶被消费者所津津乐道。在JOBCOLA可乐公司成立100周年的日子里,公司搜集了历年来生产的可乐瓶,想通过举办一个可乐瓶展览,以此来提高公司的文化品位。但是受制于展览场地的大小,只能展出一部分的瓶子。经过JOBDU董事会与展览承办商协商之后,决定选出一个连续时期的瓶子用于展览,同时为了达到最佳的美学感受,在所展览的瓶子中,最高的瓶子和最低的瓶子之间的高度,不能超过k。
    给你的任务就是,挑选出满足上述要求的最长瓶子序列,供董事会选择。
    输入:
    每个测试案例包括两行:
    第一行为两个整数,n和k,其中n代表待选的瓶子个数,k为所选出的瓶子中最高瓶子和最低瓶子之间的最大落差。其中1 <= n <= 105, 0 <= k <= 106
    第二行包含n个整数,每个整数代表瓶子的高度(单位为微米),已知所有瓶子都已经按照生产年代,从古到今进行了排序。
    输出:
    对应每个测试案例,输出的第一行包括两个整数a, b。其中a代表满足条件的瓶子个数;b则代表有多少组这样的选择方案。接下来再输出b行,每行包括两个整数s, e (1 <=s,e <=n),其中s代表所选的a个瓶子中最古老的瓶子的下标,而e则代表该方案中最近生产的瓶子下标。注意:若有多个方案,则按照s从小到大的顺序输出;若s相同,则按照e的大小输出。
    样例输入:
    3 2
    13 12 10
    样例输出:
    2 2
    1 2
    2 3

    思路:

    其实我没AC,思路还是有问题。以后找时间再AC。先贴别人的代码。


    代码:

    //ac code
    
    #include <iostream>
    #include <cstring>
    #include <algorithm>
    #include <cstdio>
    using namespace std;
    
    
    int height[100009];
    int n, k;
    int h[100009][20];
    int l[100009][20];
    int exp2(unsigned x);
    int getmax(int x, int y);
    int getmin(int x, int y);
    int Ok(int len);
    int rx[100000];
    int ry[100000];
    int main(){
            while(cin>>n>>k){
                    for(int i= 0; i< n; ++i){
                            scanf("%d", height+i);
                    }
                    for(int i= 0; i< n; ++i){
                            h[i][0]= i;
                            l[i][0]= i;
                    }
                    int x= exp2(n);
            //RMQ
                    for(int j= 1; j<= x; ++j){
                            for(int i= 0; i<= n-(1<<j); ++i){
                                    h[i][j]= h[i][j-1];
                                    l[i][j]= l[i][j-1];
                                    if(height[h[i][j]]< height[h[i+(1<<(j-1))][j-1]]){
                                            h[i][j]= h[i+(1<<(j-1))][j-1];
                                    }
                                    if(height[l[i][j]]>= height[l[i+(1<<(j-1))][j-1]]){
                                            l[i][j]= l[i+(1<<(j-1))][j-1];
                                    }
                            }
                    }
                    int low= 1, high= n;
                    int mid;
            //binary search最大值
                    while(low< high){
                            mid= (low+high)>>1;
                            if(Ok(mid)){
                                    low= mid+1;
                            }else{
                                    high= mid-1;
                            }
                    }
                    while(!Ok(low))
                            --low;
                    int a, b;
                    int count= 0;
                    for(int i= 0; i<= n-low; ++i){
                            a= getmax(i, i+low-1);
                            b= getmin(i, i+low-1);
                            if((height[a]-height[b])<= k){
                                    rx[count]=i;
                                    ry[count]=i+low-1;
                                    ++count;
                            }
                    }
                    cout<<low<<' '<<count<<endl;
                    for(int i= 0; i< count; ++i){
                            cout<<rx[i]+1<<' '<<ry[i]+1<<endl;
                    }
            }
    }
    
    int exp2(unsigned x){
            int re= 0;
            while(x){
                    x>>=1;
                    ++re;
            }
            return  re-1;
    }
    
    
    int getmax(int x, int y){
            int p= exp2(y-x+1);
            if(height[h[x][p]]>= height[h[y-(1<<p)+1][p]]){
                    return h[x][p];
            }else{
                    return h[y-(1<<p)+1][p];
            }
    }
    int getmin(int x, int y){
            int p= exp2(y-x+1);
            if(height[l[x][p]]< height[l[y-(1<<p)+1][p]]){
                    return l[x][p];
            }else{
                    return l[y-(1<<p)+1][p];
            }
    }
    
    int Ok(int len){
            for(int i= 0; i<= n-len; ++i){
                    if(height[getmax(i,i+len-1)]-height[getmin(i,i+len-1)]<= k){
                            return true;
                    }
            }
            return false;
    }


  • 相关阅读:
    2.7连接数据库中遇见的相应问题1
    linux bash中too many arguments问题的解决方法
    linux系统补丁更新 yum命令
    安装node,linux升级gcc
    python-导出Jenkins任务
    升级openssl和openssh版本
    linux修改文件所属的用户组以及用户
    linux的Umask 为022 和027 都是什么意思?
    keepalived
    自己编写k8s
  • 原文地址:https://www.cnblogs.com/liangrx06/p/5083789.html
Copyright © 2011-2022 走看看