HDU 6709 Fishing Master 容斥+贪心

http://www.caiyiwen.tech/article/8.html

  • H - Fishing Master
    • 这道题当年打网络赛的时候是想了一个策略的,但是训练时忘了,所以重新从更加数学的角度思考了一下。
    • 思路:我们总共需要n段钓鱼的时间和n段煮鱼的时间,其总和为nk+∑ti。然而我们有重合的部分需要减去,所以实际需要的时间为——nk+∑ti-重合部分。所以问题变成如何求出最大的重合部分,我们知道显然可以完全利用的时间只有煮鱼时间ti中k的整数倍,即ti%k的那一部分时间是注定会有损耗的。一开始没有鱼的时候必须花k的时间去钓一条鱼,所以如果∑(ti/k)≥n-1,总时间就直接是k+n*ti。
    • 如果∑(ti/k)<n-1,那么我们还需要n-1-∑(ti/k)段时间去钓鱼,这些时间就是ti%k的那一部分,注定浪费时间。所以我们贪心地去ti%k最大的几个ti值即可减少浪费。

代码:

#include<cstdio>
#include<algorithm>
using namespace std;
int t[(int)1e5+10];
bool cmp(int a,int b)
{
	return a>b;
}
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		long long n,k;
		scanf("%lld%lld",&n,&k);
		long long cnt=0;
		for(int i=0;i<n;++i)
		{
			scanf("%d",&t[i]);
			cnt+=t[i]/k*k;
		}
		long long sum=0;
		for(int i=0;i<n;++i)
		{
			sum+=t[i];
		}
		if(cnt>=(n-1)*k)
		{
			printf("%lld\n",k+sum);
		}
		else
		{
			for(int i=0;i<n;++i)
			{
				t[i]%=k;
			}
			sort(t,t+n,cmp);
			int red=cnt/k;
			for(int i=0;i<n-1-red;++i)
			{
				cnt+=t[i];
			}
			printf("%lld\n",n*k+sum-cnt);
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值