Description
英勇的福克斯有一个使命,从不同的行星收集尽可能多的燃料。有N个行星,第i个行星储存有Ai个单位的燃料。然而,从任何一个其他行星旅行到该行星都需要花费Bi个单位的燃料。不幸的是,燃料是不可再生的,所以当你第二次来到一个行星时,它就没有任何燃料了可以收集。
福克斯从第P个行星出发,当然他们可以立即收集该行星上的燃料。他们然后可以旅行到其他不同的行星。只要他们有足够的燃料,他们可以以任何顺序旅行。最后,他们需要选择一个行星结束旅行,他们的目标是在结束旅行时拥有最多数量的燃料,如果有很多种方法可以实现,他们希望旅行到最多的行星。你能帮助他们么?
Input
输入的第一行包含两个正整数
n
,
p
n , p
n,p,表示行星数量,以及出发的星球
接下来
n
n
n 行,每行包括两个正整数
A
[
i
]
,
B
[
i
]
A[i] , B[i]
A[i],B[i],表示第
i
i
i 个星球可以收集的燃料,到达第
i
i
i 个星球需要的燃料
Output
输出的第一行包含一个整数,表示在结束时燃料最多的数量。
第二行包含一个整数,表示在结束时燃料最多的情况下,能够到达的行星的最多数量
Sample Input
5 2
12 12
10 100
8 3
4 5
25 15
Sample Output
25
4
Data
1 ≤ n ≤ 1 0 5 , A [ i ] , B [ i ] ≤ 1 0 4 1\leq n \leq 10^5,A[i],B[i] \leq 10^4 1≤n≤105,A[i],B[i]≤104
Associate
这一道题,我上来5分钟就写完了。
觉得很简单啊,因为不管中间怎么飞行,我最后得到的永远都是每一个不亏本的星球的得到减去支出的值。所以我只需要把所有不亏本星球的差值都加一遍就行了。
但是没有想到一个问题:贷款飞行
还好我考试的时候想到了,不能贷款飞行。就是现在的燃料飞不到某一个星球去的情况。
然后我就改成了接近于正解的算法
拿到了0分
忘判断不能回到最开始的星球了。
获得了0分的好成绩
Solution
所以现在来说一下正解
我们先定义一个ans,用来记录当前的答案。
把所有的星球,根据他们的cost来排一下序(只考虑赚资源的星球,如果这个星球不赚资源就不如不去)
这样的话,我们从最小的cost开始
- 如果不能到达这个星球(当前ans小于这个星球的cost),那么我们就可以退出循环了。为什么呢?因为,既然这个星球都不能到达,因为整个序列都是排过序的,所以这个星球不能到达,后面比这个星球的cost大的星球就更不能到达了
- 如果这个星球能到达,我们就考虑把这个星球赚的资源加上
大概就是这样
Code
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <cmath>
using namespace std;
inline int read() {
int x = 0 , f = 1; char ch = getchar();
for ( ; !isdigit(ch) ; ch = getchar()) if (ch == '-') f = -1;
for ( ; isdigit(ch) ; ch = getchar()) x = x * 10 + ch - '0';
return x * f;
}
const int maxn = 1e5 + 10;
struct Node {
int value , cost;
bool operator < (const Node &k) const {
return this->cost < k.cost;
}
}node[maxn];
int cnt;
int ans;
int n , p;
bool vis[maxn];
int tmp;
int main() {
n = read() , p = read();
for (int i = 1 ; i <= n ; i ++) {
int x = read() , y = read();
if (i == p) {
ans = x;
}
else {
if (x < y) {
continue;
}
else {
node[++ cnt].value = x;
node[cnt].cost = y;
}
}
}
sort(node + 1 , node + cnt + 1);
//for (int i = 1 ; i <= cnt ; i ++) {
// cout << node[i].value << " " << node[i].cost << endl;
//}
for (int i = 1 ; i <= cnt ; i ++) {
if (node[i].cost > ans) {
break;
}
ans += (node[i].value - node[i].cost);
tmp ++;
}
printf("%d\n%d\n" , ans , tmp + 1);
}