洛谷P2878 [USACO07JAN]保护花朵Protecting the Flowers(贪心)

题目描述

Farmer John went to cut some wood and left N (2 ≤ N ≤ 100,000) cows
eating the grass, as usual. When he returned, he found to his horror
that the cluster of cows was in his garden eating his beautiful
flowers. Wanting to minimize the subsequent damage, FJ decided to take
immediate action and transport each cow back to its own barn.

Each cow i is at a location that is Ti minutes (1 ≤ Ti ≤ 2,000,000)
away from its own barn. Furthermore, while waiting for transport, she
destroys Di (1 ≤ Di ≤ 100) flowers per minute. No matter how hard he
tries, FJ can only transport one cow at a time back to her barn.
Moving cow i to its barn requires 2 × Ti minutes (Ti to get there and
Ti to return). FJ starts at the flower patch, transports the cow to
its barn, and then walks back to the flowers, taking no extra time to
get to the next cow that needs transport.

Write a program to determine the order in which FJ should pick up the
cows so that the total number of flowers destroyed is minimized.

有n头奶牛跑到FJ的花园里去吃花儿了,它们分别在距离牛圈T分钟处吃花儿,每分钟会吃掉D朵卡哇伊的花儿,(此处有点拗口,不要在意细节啊!),FJ现在要将它们给弄回牛圈,但是他每次只能弄一头回去,来回用时总共为2*T分钟,在这段时间内,其它的奶牛会继续吃FJ卡哇伊的花儿,速度保持不变,当然正在被赶回牛圈的奶牛就没口福了!现在要求以一种最棒的方法来尽可能的减少花儿的损失数量,求奶牛吃掉花儿的最少朵数!

输入输出格式

输入格式: Line 1: A single integer N

Lines 2..N+1: Each line contains two space-separated integers, Ti and
Di, that describe a single cow’s characteristics

输出格式: Line 1: A single integer that is the minimum number of destroyed
flowers

输入输出样例

输入样例#1:
6
3 1
2 5
2 3
3 2
4 1
1 6
输出样例#1:
86
说明

FJ returns the cows in the following order: 6, 2, 3, 4, 1, 5. While he
is transporting cow 6 to the barn, the others destroy 24 flowers; next
he will take cow 2, losing 28 more of his beautiful flora. For the
cows 3, 4, 1 he loses 16, 12, and 6 flowers respectively. When he
picks cow 5 there are no more cows damaging the flowers, so the loss
for that cow is zero. The total flowers lost this way is 24 + 28 + 16
+ 12 + 6 = 86.

贪心思想:设a,b是两头牛,我们想要的就是先送损失的花少的。
送b牛则a牛损失花为 Ha*Tb*2 ,送a牛则b牛损失花为Hb*Ta*2;
所以不妨让a损失 < b损失。 则Ha*Tb < Hb*Ta;
即Ha/Ta < Hb/Tb

所以按每头牛吃的花和时间的比从小到大排序的顺序处理然后就可以得到答案啦~
代码如下:

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
using namespace std;
const int maxn=200005;
typedef long long ll;
struct dqs
{
    ll ch,fz;
}hh[maxn];
bool cmp(dqs a,dqs b)
{
    return (double)a.fz/(double)a.ch<(double)b.fz/(double)b.ch;
}
int main()
{
    long long n,tim=0,ans=0;
    scanf("%lld",&n);
    for(int i=1;i<=n;i++)
        scanf("%lld%lld",&hh[i].fz,&hh[i].ch);
    sort(hh+1,hh+n+1,cmp);
    for(int i=1;i<=n;i++)
    {
        ans+=tim*hh[i].ch;
        tim+=hh[i].fz*2;
    }
    printf("%lld\n",ans);
    return 0;
}

写题时的错误贪心想法,对于每个牛求一下除他之外剩下的牛的吃花之和。用这个值*他自己移动需要的的时间,按这个从小到大排序。这个贪心想法,乍一看是对的,其实不然。因为在后期,时间和距离的影响性其实是改变了的。如 原来时间是3,吃花是2和吃花是3,时间是2,后面时间改变了(比如-1),则他们 就分别变成3和4,除非每次都sort,这样复杂度显然不够。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值