排队打水问题 (C++)

一道典型的贪心算法问题

很多解释都是把打水和等待分开,可以不分开,按列来算,找到后面人和第一个使用水龙头时间的关系即可。最终所有的t[i]相加就行。

int main()
{
	int n,r;//n 人 r 水龙头 
	cin>>n>>r;
	const int a=n;//这样就可以自定义数组大小
	int t[a],sum;
	for(int i=0;i<n;i++) 
	{
		cin>>t[i];
	}
	sort(t,t+n);
	for(int i=r;i<n;i++)//从r开始,需要算上一个人的接水时间 
	{
		t[i]+=t[i % r+(i/r-1)*r]; // 所有>=第二轮的人,都适用 
	}
	
	for(int i=0;i<n;i++)
	{
		sum+=t[i];
	}
	cout<<sum<<endl;

}

sort完之后,
第一轮打水的时间不用管,因为只有自己的时间。
第n轮的人所用时间为:自己打水的时间和上一个人所用时间之和,
例如:t[r]=t[0]+t[r]; (第二排)

第n轮的时间,都和第一轮找关系:
*t[i%r+(i/r-1)r],
这里一定不要分解因式了!!!!
因为“ / ”是整除,分解之后答案就不对啦!

i%r:第i%r个水龙头第一个人使用的时间
(i/r-1) * r :(轮数-1)*r

举个例子:
A B C (ABC三个水龙头)
0 1 2 (第一轮)(0号 1 号 2号接水人)
3 4 5 (第二轮)
6 7 8 (第三轮)
9 …

那么:

t[4]=t[1]+t[4]	//t[4] 4=1加上1个3   
t[7]=t[4]+t[7]  //t[7] 7=1加上2个3
这里的1就是余数,表明是1号对应的水龙头 几个就是(轮数-1)【找规律得】

所以就有了针对于从第二轮开始的打水人的公式:

t[i]+=t[i % r+(i/r-1)*r]; // 所有>=第二轮的人,都适用 

-end-

  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值