LA 4850 Installations (排序+枚举)
2016-12-13 09:52
411 查看
LA 4850 Installations
题目大意
有n个安装服务,第i个服务需要si时间完成,截止日期为di,若在截止日期前完成,没有惩罚,若在截止日期后完成,若完成日期为ti,惩罚值为ti-di.即惩罚值为max(0,ti-di).求如何安排任务,使得最大的两个惩罚值之和最小.题目分析
最开始把题看错了,看成是求最大的惩罚值最小,直接按照di排序.但是这种方法只能使得全局最优,并不一定是和最小.那么在此排序后的基础上,可以考虑将某个服务放在后面去,让其惩罚值变大来使得两个最大值之和最小.肯定该服务要往后移动.那么那些地方可以移动呢?实际上,只用考虑两最大值靠后的位置(以下用pos代替)以前,因为移动服务位置是要使得最大值变小,pos以后的位置并不能改变.
至于应当移动到哪里,显然是pos后方,若再往后虽然会让原pos以后的服务惩罚值变小,但是却没有意义,因为取最大值的时候不会取到,反而增加了当前服务的惩罚值,使其更可能变成最大值.
所以枚举pos以前的服务,移动到pos后方即可.
代码:
#include<cstdio> #include<iostream> #include<algorithm> using namespace std; const int maxn=500+10; struct Install { int s,d; bool operator < (const Install& rhs) const { return d<rhs.d; } void input() { scanf("%d%d",&s,&d); } }ins[maxn]; int n,pos; int find(int k)//将第k个放在pos以后的ans { int tim=0,max1=0,max2=0; for(int i=0;i<=pos;i++) if(i!=k) {//pos以后的并不需要遍历 tim+=ins[i].s; max2=max(max2,tim-ins[i].d); if(max1<max2) swap(max1,max2); } tim+=ins[k].s; return max1+max(max2,tim-ins[k].d); } int main() { int T; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i=0;i<n;i++) ins[i].input(); sort(ins,ins+n); int tim=0,max1=0,max2=0; for(int i=0;i<n;i++) {//先最开始做一遍,并记录下两个最大值靠后的一个 tim+=ins[i].s; if(max2<=tim-ins[i].d) pos=i,max2=tim-ins[i].d; if(max1<max2) swap(max1,max2); } int ans=max1+max2; for(int i=0;i<pos;i++)//尝试置换位置使得ans更优 ans=min(ans,find(i)); printf("%d\n",ans); } return 0; }
相关文章推荐
- LA 4850 Installations
- la 4850 - Installations
- LA 4850 Installations 贪心 *
- UVALive - 4850 Installations 贪心+枚举
- OC中枚举和排序
- Unity3D研究院之Inspector面板枚举的别名与排序(八十九)
- POJ 2280 几何题 经典 枚举+极角排序+旋转扫描
- 黑马程序员--.NET笔记--枚举、数组、排序、方法、变量的作用域、重载
- 1012. The Best Rank (25)暴力枚举 排序
- 二分,枚举+查找(子序列,LA 2678)
- MPI并行编程系列一:枚举排序
- hdu-1425(排序||枚举)
- HDU 4500 小Q系列故事——屌丝的逆袭(模拟枚举排序)
- LA 2402 (枚举) Fishnet
- HDU 1007 Quoit Design 仅仅只是枚举了x排序后的三个数......
- LA 4253 Archery(二分+枚举)
- ObjectC----字典类和集合类以及快速枚举和OC中的数组排序
- c笔记11---联合,枚举,堆 malloc,大/小端存储,二级指针,函数指针,qsort 排序,指针数组
- NSArray和NSMutableString,枚举和排序
- 【OC加强】枚举介绍、数组的排序、对象的排序、如何利用block排序以及一些数据类型知识