题目链接: Education
大致题意
给定n和m, 表示有n个岗位和你需要凑够m元钱.
再给定两个序列a和b, 序列a的长度为n, b的长度为n-1. a[i]表示处于第i个岗位时, 每天可以挣多少钱, b[i]表示升级到第i+1个岗位需要花费多少钱.
特别的, 当你选择升级到第i+1个岗位时, 这一天只会花费b[i]元, 并不会挣钱.
问: 至少需要多少天可以攒够m元钱.
解题思路
这个题我们只需要按照题目去模拟即可. 最终答案一定是升到某个岗位后, 停止再升, 直到赚到m元钱是最优的. 因此我们只需要分别枚举升级到每一个岗位, 需要多少天达成目标即可.
AC代码
#include <bits/stdc++.h>
#define rep(i, n) for (int i = 1; i <= (n); ++i)
using namespace std;
typedef long long ll;
const int N = 2E5 + 10;
int a[N], b[N];
ll fact(ll a, ll b) { return (a + b - 1) / b; } //ceil函数, 库函数可能会出锅.
int main()
{
int t; cin >> t;
while (t--) {
int n, m; scanf("%d %d", &n, &m);
rep(i, n) scanf("%d", &a[i]);
rep(i, n - 1) scanf("%d", &b[i]);
ll res = LLONG_MAX; //当前最优解
ll leave = 0, day = 0; //我们现在有的钱数, 和当前处于第几天
rep(i, n) {
ll need = fact(m - leave, a[i]); //提升到第i个岗位后还需要再工作的天数
res = min(res, day + need);
ll impcost = fact(b[i] - leave, a[i]); //我们提升到下一个岗位要的天数
leave = 1ll * impcost * a[i] + leave - b[i]; //此时我们还会剩多少钱
day += impcost + 1; //我们此时又度过的天数, +1是因为提升岗位也需要额外花费一天.
}
printf("%d\n", res);
}
return 0;
}