#贪心 一种不需要额外开数组的解法。 既然是要求出买新电脑的最少天数,那么最后一个可能的打工地点 $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; } ```