题目链接:https://vjudge.net/problem/UVA-11729
一道比较显然的贪心。
我们可以发现如果我们让$a_j$最大的尽可能地往前来交待,那么时间重合地会更多。
一个很明显的贪心策略:按照$j$从大到小排序,记录每一次的$s$(交代的时间)和$s+a_j$(结束的时间),用结束的时间来更新$ans$。
证明其正确性:(蓝书 P4)
可以使用最常见的交换论证法:
假设我们交换相邻的两个任务$X$和$Y$,不难发现交换前后只会对$X$和$Y$有关。
情况一:交换之前,$X$比$Y$后结束:
那交换之后$Y$结束的时间会提前很多,同样,$X$也会延迟$B[Y]$的时间结束,总的来说结束时间会延迟,所以该情况不优。
情况二:交换之前,$X$比$Y$先结束:
那交换后最终所用的时间肯定$geq$交换前所用的时间。
这个条件就可以写成:$B[y]+B[x]+J[x]geq B[x]+B[y]+J[y]$,化简之后可得$J[x]geq J[y]$。
这样就可以支持我们贪心策略的正确性。
AC代码:
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 6 using namespace std; 7 8 struct node{ 9 int b,j; 10 } a[10005]; 11 int t,n; 12 13 inline bool cmp(node x,node y){ 14 return x.j>y.j; 15 } 16 17 int main(){ 18 while(scanf("%d",&n)==1){ 19 memset(a,0,sizeof(a)); 20 t++; 21 if(n==0) break; 22 for(int i=1;i<=n;i++){ 23 scanf("%d%d",&a[i].b,&a[i].j); 24 } 25 sort(a+1,a+n+1,cmp); 26 int ans=0,s=0; 27 for(int i=1;i<=n;i++){ 28 s+=a[i].b; 29 ans=max(ans,s+a[i].j); 30 } 31 printf("Case %d: %d ",t,ans); 32 } 33 return 0; 34 }