bzoj1293 [SCOI2009]生日礼物

题目链接

单调队列优化

枚举起点找出每一种颜色在这个位置之后的第一个位置与这个位置距离的最大值。

再找出每一个起点结果的最小值。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace std;
 6 const int inf=2147483647;
 7 int n,k,sum,ans=inf,head[65],next[1000005],v[1000005],a[1000005];
 8 inline int getint()
 9 {
10     int f=1,ret=0;
11     char ch=getchar();
12     while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
13     while(ch>='0'&&ch<='9')ret*=10,ret+=ch-'0',ch=getchar();
14     return f==-1?-ret:ret;
15 }
16 bool js(int x)
17 {
18     int mx=0;
19     for(int i=1;i<=k;i++)
20     {
21         while(v[head[i]]>x)
22         {
23             if(!next[head[i]])return 0;
24             head[i]=next[head[i]];
25             }
26         if(v[head[i]]<=x)mx=max(mx,x-v[head[i]]);
27     }
28     ans=min(ans,mx);
29     return 1;
30 }
31 int main()
32 {
33     n=getint();k=getint();
34     for(int i=1;i<=k;i++)
35     {
36         int x=getint();
37         for(int j=1;j<=x;j++)
38         {
39             int y=getint();
40             v[++sum]=y,next[sum]=head[i],head[i]=sum,a[sum]=y;
41         }
42     }
43     sort(a+1,a+sum+1);
44     for(int i=sum;i>0;i--)
45     {
46         if(a[i]!=a[i+1])
47         if(!js(a[i]))break;
48     }
49     printf("%d",ans);
50     return 0;
51 }

 

posted @ 2016-01-22 14:35  HugeGun  阅读(164)  评论(0编辑  收藏  举报