比赛的时候想的是尽量先炖鱼,果然还是赛后牛逼,反应过来无论怎样总时间内一定有所有的炖鱼时间,所以只需要尽量缩减我们的钓鱼时间即可。
一、在炖鱼时间内可以把所有鱼都钓上来,那ans = k + t[1~n]
二、不能在炖鱼时间内把所有鱼都钓上来
即每次钓一条鱼上来后,鱼都会煮过。
如钓鱼时间为2,炖鱼时间为1,钓鱼上来后,炖的鱼煮过了1分钟。
而钓鱼时间为2,炖鱼时间为3,钓第一条鱼上来后,鱼还没煮熟,钓第二条鱼后才煮过1分钟,因此这时候可以在炖鱼时间内不花多的时间钓上来至少一条鱼。
由于我们可选择钓上来的鱼的先手顺序,因此我们可在煮鱼时间在x = (1~k-1)内尽量大的鱼中选择,即选择k - x尽量小的鱼,这样的话我们在炖鱼的时候多钓一条鱼所花费的时间就尽量的小。
所以从大到小排序后求前n-1条鱼被煮时间内可钓的鱼,判断是否可在时间内钓完所有鱼。
代码如下:
#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N = 100010;
ll te[N], d[N];
int main()
{
int T;
scanf("%d", &T);
while(T--){
ll n, k;
scanf("%lld%lld", &n, &k);
ll min = 1e9+7;
ll sum = 0;
for(int i = 1; i <= n; i++){
scanf("%lld", &te[i]);
sum += te[i] / k;
if(min > te[i]) min = te[i];
}
sum -= min / k;
ll time = k;
for(int i = 1; i <= n; i++) time += te[i];
if(sum < n - 1){
for(int i = 1; i <= n; i++) d[i] = k - (te[i] % k);
sort(d + 1, d + 1 + n);
for(int i = 1; i <= n - 1 - sum; i++) time += d[i];
}
printf("%lld\n", time);
}
return 0;
}