九度OJ 1344:可乐瓶展览 (DP)

来源:互联网 发布:js中jsonarray 编辑:程序博客网 时间:2024/05/09 02:17

时间限制: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 213 12 10
样例输出:
2 21 22 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;}


0 0
原创粉丝点击