题意
需要购买一个玩具费用为c,他有一个机器,每使用一天会给他一定的费用,机器的有n个等级,等级越高的得到的钱也会多,等级为i得到的钱为ai(ai+1 >= ai),初始时刻机器的等价为1,机器每次升级需要花费bi,他在每天可以有两种操作:
1.使用机器,获得ai的钱
2. 给机器升级花费bi (必须他的钱最够多才能升级
求最少需要多少天。
思路
最小需要的天数,且是一个单调问题所以可以使用二分来算,
二分天数判断第mid天对应各个等级能够生成钱能否大于c,在这之前就需要先知道升级的i需要的最小天数,以及剩余的钱。(因为ai+1 >= ai,所以能最早升级就最早升级)计算这个可以直接线性遍历一遍。
代码
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<unordered_set>
#include<unordered_map>
using namespace std;
#define x first
#define y second
#define int long long
typedef pair<int ,int > PII;
typedef long long ll;
const int N = 2e5 + 10;
int f[N],g[N];
int a[N],b[N];
int n,c;
void init(){
f[1] = 0;
g[1] = 0;
for(int i = 2;i <= n;i++){
int d = (b[i - 1] - g[i - 1] + a[i - 1] - 1) / a[i - 1];
f[i] = f[i - 1] + d + 1;
g[i] = g[i - 1] + a[i - 1] * d - b[i - 1];
// cout << f[i] << ' ' << g[i] << endl;
}
}
bool check(int mid){
for(int i = 1;i <= n;i++){
if(f[i] > mid) return false;
int ans = g[i] + a[i] * (mid - f[i]);
if(ans >= c) return true;
}
return false;
}
signed main(){
int T;
scanf("%lld",&T);
while(T--){
scanf("%lld%lld",&n,&c);
for(int i = 1;i <= n;i++) scanf("%d",&a[i]);
for(int i = 1;i <= n - 1;i ++) scanf("%d",&b[i]);
init();
int l = 0,r = 1e9;
while(l < r){
int mid = (l + r) >> 1;
if(check(mid)) r = mid;
else l = mid + 1;
}
cout << r << endl;
}
return 0;
}