比赛的时候想的是尽量先炖鱼,果然还是赛后牛逼,反应过来无论怎样总时间内一定有所有的炖鱼时间,所以只需要尽量缩减我们的钓鱼时间即可。

一、在炖鱼时间内可以把所有鱼都钓上来,那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;
}