David 作为一名 scut的大学生,自然需要去学习。
在 scut,有N门不同的课程,一个学期一共有M周,对于每一周,会上N次课,每一门课程恰好一周上一次课,David对于每一个课程都有一个熟练度,初始时都为 0。
对于一节课 David可以选择如下选项中的一个:
• 去上课:如果他上的是第i门课,那么他对于这节课的熟练度增加Ai。
• 翘课:David热爱学习,所以他会选一门课自学,如果他选了第i门课,那么他对于这节课的熟练度增加Bi。
为了去更多的学习课外知识,David不会在课下学习这N门课程,但是他又不想要让自己挂科,于是他找到了你,他想让自己对每一门课的熟练度的最小值最大。
第一行两个整数N,M
接下来一行N个整数Ai。
接下来一行N个整数Bi。
解释
举个例子,如果David按如下方式学习,则他对课程1,2,3的理解程度将分别为19,18,19。
第一周课程1的课:翘课自学课程2;
第一周课程2的课:翘课自学课程2;
第一周课程3的课:去上课程3的课;
第二周课程1的课:去上课程1的课;
第二周课程2的课:翘课自学课程3;
第二周课程3的课:去上课程3的课:
第三周课程1的课:翘课自学课程3;
第三周课程2的课:翘课自学课程2;
第三周课程3的课:去上课程3的课。。
数据范围
1<=N<=3*10^5,1<=M,Ai,Bi<=10^9
提示:
1.本题主要算法为二分答案,check函数中运用到贪心的思想
2.所有数据都开long long
3.自己写一个上取整函数,double可能有丢精度问题
4.二分主要代码
#include <iostream>
#define ll long long
using namespace std;
ll a[300010],b[300010];
ll n, m;
ll ceil(ll x, ll y) {
}
bool check(ll k) {//最小为k
}
int main(){
cin >> n >> m;
for (int i = 1; i <= n; i++) cin >> a[i];
for (int i = 1; i <= n; i++) cin >> b[i];
ll left = 0, right = 1e18+1000;
while (left + 1 < right) {
ll mid = left + right >> 1;
if (check(mid)) left = mid;//课时数够,提高要求
else right = mid;
}
// [[[[[[ ))))) 满足课时数"[" 的最大值答案在left
cout << left;
return 0;
}