我发现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; }