1852: 松鼠与栗子(New Online Judge)
题目描述
现在有m棵栗子树,n只松鼠在等待栗子下落。
第i棵树的第一个栗子在t[i],之后每p[i]秒都掉落一个。
现在松鼠们希望最终能获得k个栗子,每只松鼠将选择一棵栗子树等待。
不考虑松鼠移动到每棵树的时间,只考虑等待时间。
请求出最优情况下的最少的等待时间,即松鼠选择最优情况下的n个栗子树进行等待,等待时间最小是多少。
输入
第一行为正整数m,n,k。 1 ≤ n ≤ m ≤ 10000 , 1 ≤ k ≤ 1 0 7 1≤n≤m≤10000,1≤k≤10^7 1≤n≤m≤10000,1≤k≤107。
第二行包含m个整数表示t[i]。
第三行包含m个整数表示p[i],1≤t[i],p[i]≤100。
输出
输出一个数字表示答案。
样例输入
样例1:
3 2 5
5 1 2
1 2 1
样例2:
3 2 5
5 1 2
1 1 1
样例输出
样例1:
4
样例2:
3
题解1(C++版本)
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e4 + 10;
int m, t[N], p[N], k, n, num[N];
bool cmp(int a, int b){
return a > b;
}
bool check(int x){ //判断等待时间为x的情况下,掉落栗子数量是否>=k
LL sum = 0; //在等待时间够大的情况下,掉落的栗子数量可能会超出int类型的最大值
memset(num, 0, sizeof num);
for(int i = 1; i <= m; i++){
if(t[i] > x) continue;
num[i] = (x - t[i])/p[i] + 1; //在等待时间为x的情况下,第i棵树掉落的总栗子数量
sum += num[i];
//printf("x = %d i = %d num = %d\n", x, i, num[i]);
}
if(sum < k) return false;
sort(num + 1, num + m + 1, cmp); //选择掉落栗子数量最多的前n棵树
LL res = 0;
for(int i = 1; i <= n; i++) res += num[i];
return res >= k;
}
int main(){
scanf("%d%d%d", &m, &n, &k);
for(int i = 1; i <= m; i++) scanf("%d", &t[i]);
for(int i = 1; i <= m; i++) scanf("%d", &p[i]);
int L = 0, R = 1e9 + 7, mid;
while(L + 1 < R){
mid = (L + R)/2;
if(check(mid)) R = mid; //二分答案
else L = mid;
}
printf("%d\n", R);
return 0;
}