BZOJ 1293 生日礼物

我发现BZOJ的水题都比较高档昂。这道题的基本思想是,每次用优先队列把位置最靠前的颜色弹出来,并把与它颜色相同的下一个点的位置进队列,每次更新最优长度。

    1.初始化:每个点的下一个相同颜色点的位置。

    2.将每个颜色的第一个点入队列,算第一个状态。

    3.每次将队列最前端的颜色弹出,将他的下一个点放入队列,更新最优长度。

注:cmp函数、重载运算符有的时候需要加“const”“&”等奇怪的符号,一直都不太懂什么意思,怎么用,求神犇指教。

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<utility>
#include<queue>
#define MAXN 1000010
#define INF (1<<30)
using namespace std;
int t[61],s[61];
struct node{
    int first;
    int second;
    int next;
    node(){};
    void init(int x,int y,int z){
        first=x;
        second=y;
        next=z;
    }
    friend bool operator < (node a,node b){
        return a.second>b.second;
    }
}x[MAXN];
priority_queue<node> q;
int main(){
    s[0]=0;
    int n,k,l,r=0;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=k;i++){
        scanf("%d",&s[i]);
        s[i]=s[i]+s[i-1];
        for(int j=s[i-1]+1;j<=s[i];j++) {
            int a;
            scanf("%d",&a);
            x[j].init(i,a,j+1);
        }
    }
    for(int i=0;i<k;i++) {
        r=max(r,x[s[i]+1].second);
        q.push(x[s[i]+1]);
    }
    int ans=r-q.top().second;
    while(1){
        node tmp=q.top();
        q.pop();
        if(tmp.next-1<s[tmp.first]) {
            r=max(x[tmp.next].second,r);
            q.push(x[tmp.next]);
        }
        else break;
        tmp=q.top();
        ans=min(r-tmp.second,ans);
    }
    printf("%d",ans);
    return 0;
}


猜你喜欢

转载自blog.csdn.net/u011431896/article/details/34841183
今日推荐