题目链接:
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;
}