题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=6709
题意:
n n n条鱼,抓每条鱼需要 k k k分钟,煮每条鱼至少需要 t i t_i ti分钟,可以在煮鱼的时候去抓鱼,但不能在抓鱼的时候去捕鱼,问最少花费时间。
题解:
这里不确定的就是,在煮鱼的过程中,到底是先去抓鱼还是再等等。
所以不如先把一定能确定的考虑掉,即当 k ≤ t i k\leq t_i k≤ti的时候,我们肯定是先抓 t i k \frac{t_i}{k} kti条鱼,至于剩下的 t i % k t_i\%k ti%k,不如等等考虑。
所以说,我们一定能抓的鱼的数量就能确定了,即 c n t = 1 + ∑ t i k cnt=1+\sum \frac{t_i}{k} cnt=1+∑kti(这里+1是因为最开始第一条鱼一定要抓)
现在来考虑是等还是先去抓了在来把煮的鱼捞起来
现在每个 t i t_i ti不确定的时间为 t i % k t_i\%k ti%k,不妨记做 T i T_i Ti,现在只有两种情况:
①直接等,那么花费时间为 T i T_i Ti
②先去抓鱼在来,那么你空闲的没有煮鱼的时间就是 k − T i k-T_i k−Ti,也就是没有充分利用的时间,被你浪费了
那么现在已经抓的鱼有 c n t cnt cnt条,剩下 s u m = n − c n t sum=n-cnt sum=n−cnt条没有抓,为了耗时最少,我们肯定是要让浪费的时间最少,也就是选取 s u m sum sum条浪费时间最少(即 T i T_i Ti最大的sum条),其余的煮鱼都是等待(加上等待时间),这样就是答案了。
代码:
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define sz sizeof
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> Pair;
const int MAX = 1e5 + 10;
ll n, k;
ll t[MAX];
int main() {
#ifdef ACM_LOCAL
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
int T;
scanf("%d", &T);
while (T--) {
scanf("%lld%lld", &n, &k);
ll sum = n - 1, cnt = 1;
for (int i = 1; i <= n; i++) {
scanf("%lld", &t[i]);
sum -= t[i] / k;
cnt += t[i] / k;
t[i] %= k;
}
sort(t + 1, t + 1 + n);
ll ans = cnt * k;
for (int i = n; i >= 1; i--) {
if (sum > 0)ans += k, sum--;
else ans += t[i];
}
printf("%lld\n", ans);
}
return 0;
}