洛谷 T2691 桶哥的问题——送桶

嗯...

 

题目链接:https://www.luogu.org/problem/T2691

这道题有一点贪心的思想吧...并且思路与题目是倒着来的(貌似这种思路已经很常见的...

先举个栗子:

引出思路:按结束时间早晚排序,因为没有多早的限制,但是最晚送到的时间却有限制。把时间倒流,把时间轴倒着看,首先t初始化为max(b[i]),然后枚举一遍,如果当前t大于b[i],那在t的时候不可能到达,所以要把t改为b[i]。并且t要减去消耗时间a[i]。

初始值为最后一个送到的时间,往前推,如果前面的一个送餐时间限制比后面的时间节点(例如F)减去送餐时间(EF)晚的话,那么就把前一段送餐时间用减去,因为在两个重合(GH和EF)时间段内,在实际情况下不可能同时送两个餐,那么最紧凑的排列方法就是往前挨着叠加,那么t就变成了F(横坐标)减去EF和GH的长度,得到一个新的横坐标,再往前和前一个完成时间限制点(B)比较,看哪个更晚。

如果后面的时间节点(例如F)减去送餐时间(EF)比前面的一个送餐时间限制晚的话,就意味着最短时间限制提前到了当前的时间限制点,因为只要安排得当的话,从当前时间限制点以后的时间不会对最早时间造成任何影响!那么我们就把t提前到当前的时间限制点,继续往前推就行了。

AC代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 //时间倒流 
 5 using namespace std;
 6 
 7 const int maxn = 1e6 + 5;
 8 
 9 int n;
10 struct node{
11     int a, b;
12 } e[maxn];
13 
14 inline bool cmp(node x, node y){
15     return x.b > y.b;
16 }
17 
18 int main(){
19     scanf("%d", &n);
20     for(int i = 1; i <= n; i++)
21         scanf("%d%d", &e[i].a, &e[i].b);
22     sort(e + 1, e + 1 + n, cmp);
23     int t = e[1].b;
24     for(int i = 1; i <= n; i++){
25         if(t > e[i].b) t = e[i].b;
26         t -= e[i].a;
27     }
28     printf("%d\n", t);
29     return 0;
30 } 
AC代码

猜你喜欢

转载自www.cnblogs.com/New-ljx/p/11246843.html