[SCOI2009]生日礼物(尺取法)

暴力出奇迹 考前刷水

因为懒得写单调队列/优先队列,这里给出一个劣质的O(nk)做法,可能会被卡常(看你写的常数是否优秀了)成80/90(我第一次在luogu交就90),保险起见开O2很稳的。首先把每种颜色最靠前的加入,然后统计最大值减最小值作为初始的ans。然后每次将所有颜色中当前位置最靠前的那种颜色往后移动一格(若为该颜色最后的位置则可以退出了),暴力找最大、最小值,更新ans。易知答案就在其中。

#include<bits/stdc++.h>
using namespace std;
int n,k,mn,mx,pos,ans,a[65];
vector<int>G[65];
int main()
{
    scanf("%d%d",&n,&k);
    for(int i=1,x,y;i<=k;i++)
    {
        scanf("%d",&x);
        while(x--)scanf("%d",&y),G[i].push_back(y);
    }
    mn=mx=G[1][0];
    for(int i=2;i<=k;i++)mn=min(mn,G[i][0]),mx=max(mx,G[i][0]);
    ans=mx-mn;
    while(1)
    {
        mn=G[1][a[1]],pos=1;
        for(int i=2;i<=k;i++)if(G[i][a[i]]<mn)mn=G[i][a[i]],pos=i;
        a[pos]++;
        if(a[pos]==G[pos].size())break;
        mn=mx=G[1][a[1]];
        for(int i=2;i<=k;i++)mn=min(mn,G[i][a[i]]),mx=max(mx,G[i][a[i]]);
        ans=min(ans,mx-mn);
    }
    printf("%d",ans);
}
View Code

猜你喜欢

转载自www.cnblogs.com/hfctf0210/p/10914189.html