Chieh's Blog

Because Of Coding

UVALive - 4850 Installations

Chieh posted @ 2015年2月04日 12:35 in UVALIVE , 808 阅读

飞机票:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=16762

题意:给你n个服务,然后每个服务有时间di,和执行时间si,如果执行后的时间超过di,则惩罚值为max(0,最终的时间-di),求最大两个惩罚值相加最小。

分析:二分套二分套二分,复杂度logn*n*logn*n。。。ORZ

第一个二分是确定两个和最小值用的,假设当前检测的值是x,则我们枚举每个服务,然后第二个二分,二分x的值,且l要大于等于x/2向上取整,r为x,这个是为了确定两个其中一个比较大的值,那么另一个值就可以为x-大的值,然后第三个二分,用来确定k应该插入到哪里去,假设大的值为i,小的值为j,则每个服务的d值都得家j,但是k的d值要加i,应该能理解,然后不是属于k的我们只要排序一次就够了,因为加了跟没加排序不变,然后用第三个二分把k插进去,按更新后的d从小到大,why??因为d越大的话,它的可用区域越大,贪心~所以把小的先处理,如果当前执行的任务超过了当前的d,如果是k,那就是说明k更新的值太小,所以第二个二分的l=mid+1,如果不是k,且超过了,那个r=mid-1,k太大~,如果可以,那么就说明当前方案是可以的,更新第一个二分。。。最后输出,over,啪啪啪,AC~

/*
Author:Chieh
Because of You
*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
#include <map>
#include <vector>
#include <stack>
#define LL long long
using namespace std;
const int maxn=5*123;
struct he
{
    int s,d;
} JLJ[maxn];
int T,n;
bool cmp(he a,he b)
{
    return a.d<b.d;
}
void init()
{
    scanf("%d",&n);
    for(int i=1; i<=n; i++)scanf("%d%d",&JLJ[i].s,&JLJ[i].d);
}
vector<he> V;
int isOK(int x,int y,int idx)
{
    int l=0;
    int r=V.size()-1;
    while(l<=r)
    {
        int mid=(l+r)/2;
        if(V[mid].d+y>JLJ[idx].d+x)
        {
            r=mid-1;
        }
        else
        {
            l=mid+1;
        }
    }
    V.insert(V.begin()+l, JLJ[idx]);
    int ip=l;
    int before=0;
    for(int i=0; i<V.size()-1; i++)
    {
        int tm=y;
        if(i==ip)tm=x;
        int s=V[i].s;
        int d=V[i].d+tm;
        if(s+before>d)
        {
            V.erase(V.begin()+ip);
            if(i==ip)return 1;
            return 2;
        }
        else before+=s;
    }
    V.erase(V.begin()+ip);
    return 0;
}
bool check(int x)
{

    for(int i=1; i<=n; i++)
    {
        V.erase(V.begin()+i-1);
        int l=x/2;
        int r=x;
        if(x%2!=0)l++;
        while(l<=r)
        {
            int mid=(l+r)/2;
            int t=isOK(mid,x-mid,i);
            if(t==0)
            {
                V.insert(V.begin()+i-1,JLJ[i]);
                return 1;
            }
            if(t==1)
            {
                l=mid+1;
            }
            else
            {
                r=mid-1;
            }
        }
        V.insert(V.begin()+i-1,JLJ[i]);
    }
    return 0;
}
void play()
{
    sort(JLJ+1,JLJ+1+n,cmp);
    V.clear();
    for(int j=1; j<=n; j++)
    {
        V.push_back(JLJ[j]);
    }
    he a;
    a.s=0;
    a.d=2000000000;
    V.push_back(a);
    int l=0;
    int r=1000000;
    int MIN=1000000000;
    while(l<=r)
    {
        int mid = (l + r) / 2;
        if(check(mid))
        {
            MIN=min(mid,MIN);
            r=mid-1;
        }
        else
        {
            l=mid+1;
        }
    }
    printf("%d\n",MIN);
}
int main()
{
    scanf("%d",&T);
    while(T--)
    {
        init();
        play();
    }
    // cout << "Hello world!" << endl;
    return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter