Protecting the flowers

该博客介绍了一种经典贪心算法的应用,即如何确定最优顺序将破坏花朵的奶牛运回谷仓以最小化损失。题目中,农夫约翰面临的问题是他的奶牛在花园里破坏花朵,而他每次只能运送一头奶牛。每头牛的运输时间和破坏花朵速率不同。通过建立贪心策略,按运输时间与破坏速率之比排序奶牛,可以找到最小化花朵破坏的顺序。博客提供了详细的算法思路和C++代码实现,并特别指出数据类型需使用Longlong以及注意第一头牛不吃花的细节。

时间限制:C / C ++ 1秒,其他语言2秒
空间限制:C / C ++ 32768K,其他语言65536K
64位IO格式:%lld
描述
农夫约翰去砍伐木头,照例让N(2≤N≤100,000)头牛吃草。当他返回时,他惊骇地发现,那群母牛在他的花园里吃着他美丽的花朵。为了最大程度地减少后续损失,FJ决定立即采取行动,将每头母牛运回自己的谷仓。
每头奶牛i的位置距离自己的牛舍都只有Ti分钟(1≤Ti≤2,000,000)。此外,在等待运输时,她每分钟会破坏Di(1≤Di≤100)花。无论他多么努力,FJ一次只能将一头母牛运回她的谷仓。将奶牛i移到谷仓需要2×Ti分钟(Ti到达那里,Ti返回)。FJ从花丛开始,将母牛运到谷仓,然后走回花朵,无需花费额外的时间即可到达需要运输的下一头母牛。
编写一个程序来确定FJ拣起奶牛的顺序,以使被破坏的花朵总数最小化。
输入描述:
第1行:单个整数N
行2…N + 1:每行包含两个以空格分隔的整数Ti和Di,它们描述了单头母牛的特征
输出描述:
第1行:单个整数,它是销毁花朵的最小数量

输入

6
3 1
2 5
2 3
3 2
4 1
1 6

输出

86

思路:算法核心:贪心
经典贪心题
假设最优的选择顺序为 …AB…,那么交换 AB 的顺序这一操作不会对其他牛产生任何影响.
由于我们已经假设最优选择顺序为 …AB…,所以 …BA… 的结果不应该比之前的好. 即 AB 应该不比 BA 差.
AB时,A吃花量Td[A],B吃花量(T+t[A])d[B]
BA时,A吃花量(T+t[B])d[A],B吃花量Td[B]
由于AB<=BA,联立推出A.t
B.d<B.t
A.d,找到最优顺序,按照此顺序排序即可。
注意有俩个小坑,数据类型要Long long!!!还有第一头牛不吃花!!!

//牛吃fafa 
//贪心,按照t/d排序 
#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
struct cow
{
	ll ti,d;
	ll  flo,sum_t;//flo是数到每头牛破坏花的总和,sum_t是从第一头到当前牛所耗的全部时间 
}t[100005];
bool cmp(cow a,cow b)
{
	return a.ti*b.d<b.ti*a.d;//排序 
}
int main()
{
	int i,n;
	cin>>n;
	for(i=1;i<=n;i++)	cin>>t[i].ti>>t[i].d;
	sort(t+1,t+n+1,cmp);
	t[1].flo=0;//注意雷区,第一头牛没破坏花 
	t[1].sum_t=2*t[1].ti; 
	for(i=2;i<=n;i++)
	{
		t[i].sum_t=t[i-1].sum_t+2*t[i].ti;//更新所用时间 
		t[i].flo=t[i-1].flo+t[i].d*t[i-1].sum_t;//更新当前牛破坏花的和 
	}
	cout<<t[n].flo<<endl;//输出 
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值