#贪心
一种不需要额外开数组的解法。
既然是要求出买新电脑的最少天数,那么最后一个可能的打工地点 $i$ 的日薪 $a_i$ 一定是 $a_1\sim a_i$ 当中最大的那个,不然我晋升上来有什么意义是不是?还浪费了钱去学习。因此,我们可以将打工的过程分为两部分:
- 从第一个位置干到满足条件的位置 $i$;
- 在 $i$ 位置上一直干到能够买一台新电脑。
但是,我们从 $1$ 干到 $i$ 所经过的所有位置当中只有日薪比前面优的才会在哪里停留打工,不然在上一个日薪更高的地方一直打工一遍凑齐不久是了?
因此,我们可以看出来了,这是一个分段的问题。实现就很简单了,当遇到一个 $a_i$ 比 $a_1\sim a_{i-1}$ 都要大的 $i$ 时,就在上一个地方一直打工知道赚完到 $i$ 的钱,然后移到 $i$,计算剩余的钱,求出在最后 $i$ 打工买电脑的天数加起来,取最小值就行了。
```cpp
#include <iostream>
using namespace std;
using LL = long long;
const LL kMaxN = 2e5 + 5;
LL a[kMaxN], b[kMaxN], ned, t, n, cost, tim, sum, cnt, has, m, ans;
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
for (cin >> t; t; t--) {
cin >> n >> cost;
m = sum = ned = has = tim = 0;
ans = 1e18;
for (LL i = 1; i <= n; i++) {
cin >> a[i];
}
for (LL i = 1; i < n; i++) {
cin >> b[i];
}
for (LL i = 1; i <= n; i++) {
if (a[i] > m) {
LL days = max(0LL, m ? (ned - sum + m - 1) / m : 0); // 需要工作的天数
sum = sum + days * m - ned; // 升级之后留下来的钱
ans = min(ans, has + days + tim + (cost - sum + a[i] - 1) / a[i]); // 在当前位置打工
has += days + tim; // 累加 1-i 已经经过的天数
m = a[i]; // 更改最大值
ned = tim = 0; // 清空
}
ned += b[i]; // 晋升所需要的钱
tim++; // 看视频的天数
}
cout << ans << '\n';
}
return 0;
}
```