第三题:T3打工旅行
标签:贪心
题意:给定一条线段从
1
1
1到
n
n
n,通过第
i
i
i个位置,花费
c
i
c_i
ci,在第
i
i
i个位置,打工一天能够赚
a
i
a_i
ai
求从位置
1
1
1到位置
n
n
n,需要最少打工天数。在同一个位置可以打工任意多天工。
题解:从通过第
i
i
i个位置考虑,想让赚的钱多,需要的天数少,肯定是在前
i
i
i天中赚钱最多的那天,多几天工比较划算。举个例子:比如要通过第
3
3
3个位置,需要花费
100
100
100。
第
1
1
1个位置打工一天能赚
10
10
10
第
2
2
2个位置打工一天能赚
20
20
20
第
3
3
3个位置打工一天能赚
15
15
15
那我们肯定选择第
2
2
2个位置的时候,多打
5
5
5天工,去凑着通过第
3
3
3个位置需要花费的这
100
100
100块钱。
我们还得维护一个当前赚的钱的剩余量,比如打工赚的钱是
75
75
75,通过某个位置需要
70
70
70,那剩余的
5
5
5块钱是可以给后面的位置去使用的。
按照这样的思路,我们一天天模拟过去,当前赚的钱的剩余量够就直接减去通过该位置的费用,不够的话就去 找前
i
i
i天中打工一天最多能赚的钱,然后算天数,更新总天数和剩余的钱。
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll N = 3e5 + 10;
ll n, a[N], c[N];
int main() {
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> a[i] >> c[i];
}
// mx: 前i天中打工一天最多能赚的钱
// day: 打工的天数 sum: 当前赚的钱的剩余量
ll mx = 0, day = 0, sum = 0;
for (int i = 1; i <= n; i++) {
mx = max(mx, a[i]);
if (sum < c[i]) {
// 不能被整除 额外加1天
ll t = (c[i] - sum + mx - 1) / mx;
day += t;
sum = sum + t * mx - c[i];
} else {
sum = sum - c[i];
}
}
cout << day << endl;
return 0;
}