您的位置:首页 > 其它

UVALive 4850 Installations

2017-10-13 20:38 316 查看
  题目大意:有若干个任务,每个任务耗时si,期限为di,同一时间只能做一个任务。对于一个任务,惩罚值为max(0,完成时间-期限)。问怎么安排,使(最大惩罚值+次大惩罚值)最小,O(n^2)。

  如果没有次大惩罚值,就是一个很显然的贪心了:把任务按di排序,di相同按si排序,一路平推过去。

  这样可以保证最大值最小,但不能保证(最大+次大)最小。好在这题有十分良心的样例:

[b] 

#include    <iostream>
#include    <cstdio>
#include    <cstdlib>
#include    <algorithm>
#include    <vector>
#include    <cstring>
#include    <queue>
#include    <complex>
#include    <stack>
#define LL long long int
#define dob double
#define FILE "4850"
using namespace std;

const int N = 100010;
struct Pair{
int t,r;
bool operator <(const Pair &p)const{
if(r==p.r)return t<p.t;
return r<p.r;
}
}A
;
int n,id,Ans,L
,R
;

inline int gi(){
int x=0,res=1;char ch=getchar();
while(ch>'9'||ch<'0'){if(ch=='-')res*=-1;ch=getchar();}
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*res;
}

inline int getmxp(){
int sum=0,mxp=0,nmxp=0;id=0;
for(int i=R[0],p;i<=n;i=R[i]){
sum+=A[i].t;p=max(0,sum-A[i].r);
if(p>=mxp)nmxp=mxp,mxp=p,id=i;
else if(p>=nmxp)nmxp=p,id=i;
}
return mxp+nmxp;
}

inline void solve(){
n=gi();R[0]=1;L[n+1]=n;
for(int i=1;i<=n;++i)
A[i].t=gi(),A[i].r=gi(),L[i]=i-1,R[i]=i+1;
sort(A+1,A+n+1);Ans=getmxp();
if(!Ans){printf("0\n");return;}
for(int i=R[0],j=id;i!=j;i=R[i]){
int l=L[i],r=R[i];
R[l]=r;R[i]=R[j];R[j]=i;
Ans=min(Ans,getmxp());
R[j]=R[i];R[l]=i;R[i]=r;
}
printf("%d\n",Ans);
}

int main()
{
freopen(FILE".in","r",stdin);
freopen(FILE".out","w",stdout);
int Case=gi();while(Case--)solve();
fclose(stdin);fclose(stdout);
return 0;
}


Installations
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: