T2691 桶哥的问题——送桶

现在这里orz 暗い之殇 orz大佬的思路~本蒟蒻看懂了~

 

题目背景

 

@桶哥

买完了桶,桶哥要去送桶。

 

题目描述

 

桶哥买了nn个桶, 他要将这些桶送去nn个人的家。他送第ii个桶需要a_iai的时间,需要在b_ibi之前送到。桶哥很懒,他想要尽量晚起身去送桶。问他最晚什么时候要去送桶?

桶哥在送完一个桶之后可以紧接着去送另一个桶。

 

输入格式

 

一行一个整数nn,以下nn行每行两个整数表示a_iaib_ibi.

 

输出格式

 

一行一个整数,表示桶哥最晚什么时候起身。

 

输入输出样例

 

输入 #1复制
4
1 6
2 7
2 8
1 7
输出 #1复制
2

 

说明/提示

 

样例说明:

桶哥在第2秒去送第1个桶,第3秒送到。

桶哥在第3秒去送第2个桶,第5秒送到。

桶哥在第5秒去送第4个桶,第6秒送到。

桶哥在第6秒去送第3个桶,第8秒送到。

不要问我他为什么会跑得那么快或那么慢。

对于20%数据,n \leq 10, 1 \leq a_i, b_i \leq 1000n10,1ai,bi1000

对于60%数据,n \leq 1000, 1 \leq a_i, b_i \leq 10^4n1000,1ai,bi104

对于100%数据,n \leq 10^6, 1 \leq a_i, b_i \leq 10^9n106,1ai,bi109

保证答案大于等于0.

思路详解

题目中强调了保证答案大于等于0,说明答案一定是有解的。

对于如何安排,运用小学的数学知识可的,尽量将任务向后安排,最好是卡在结束时间完成,这样的目的是为了避免与其他任务发生冲突,可以让其他任务继续合理安排,这样的话才是最优解。

 

 

 

贴着结束时间点了完成任务后,那么红色的那一部分我们就不用考虑了,因为做不了其他任务;

 

 

 

综上所述,可得到一下思路:

1,将结束时间从大到小排序,让结果sum等于最大的一个

2,用结果sum减掉结果所用的时间

开始划重点:3,将当前结果sum与其他任务的结束点比较,如果sum小于其他任意一个结束点的值,那么替换,用ans减掉对应时间

4,重复2的步骤一直到结束

 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓

图解: 

1.找到一个结束时间最大的任务---任务一(结束时间为6),此时sum=6;减去当前任务所需的时间,更新ans=6-2=4;

 

2.来到了第二个任务:发现该任务的结束时间点为3,比当前的sum要小!于是我们更新sum=b2=3,再减去当前任务的时间,更新sum=3-1=2;

那么最后的答案就是2了! 

多次模拟以后,我们就懂得其中的巧妙用意了:

还是上面的例子,如果第二步没有使sum=b2,那么我们就会这样放置第二个任务:

AC代码如下:

 1 /*桶哥买了nn个桶, 他要将这些桶送去nn个人的家。他送第ii个桶需要a_ia的时间,需要在b_ib 之前送到。桶哥很懒,他想要尽量晚起身去送桶。问他最晚什么时候要去送桶?
 2 输入格式
 3 一行一个整数nn,以下nn行每行两个整数表示a_ia 
 4 输出格式
 5 一行一个整数,表示桶哥最晚什么时候起身。*/
 6 #include<bits/stdc++.h>
 7 using namespace std;
 8 int re()
 9 {
10     char ch=getchar();
11     int a=0,x=1;
12     while(ch<'0'||ch>'9') 
13     {
14     if(ch=='-') x=-x;
15     ch=getchar();    
16     }
17     while(ch>='0'&&ch<='9')
18     {
19         a=a*10+(ch-'0');
20         ch=getchar();
21     }
22     return a*x;
23 }
24 int n;
25 struct t
26 {
27     int da,ti;
28 }a[1000001];
29 int cmp(t x,t y)
30 {
31     return x.da>y.da;
32 }
33 int main()
34 {
35     n=re();
36     for(int i=1;i<=n;i++)
37     {
38         a[i].ti=re();
39         a[i].da=re();
40     }
41     sort(a+1,a+1+n,cmp);
42     long long sum=a[1].da;
43     for(int i=1;i<=n;i++)
44     {
45         if(sum>a[i].da) sum=a[i].da;
46         sum-=a[i].ti;
47     }
48     cout<<sum;
49     return 0;
50 }

 

 

转载于:https://www.cnblogs.com/Michael666/p/11242384.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值