[日常摸鱼]Luogu2878 [USACO07JAN]Protecting the Flowers

直接贴题面x

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


话说题面好像有点问题…应该是在抓奶牛的路上这个奶牛好像就不会吃花了,也就相当于一下子到奶牛那边然后花了$2T$的时间带回去。

很显然的贪心,问题的关键在于怎么求出一个抓奶牛的顺序让被吃的花最少。

假设现在的顺序是$...ij...$这样,对于$i$前面的一段假如总时间的$T$,那么这时候被吃掉的花就是$T*d_i+(T+2t_i)*d_j$,如果交换了$i,j$,那就是$T*d_j+(T+2t_j)*d_i$,如果交换后比交换前大那不如不交换,化简一下就变成了$t_j d_i > t_i d_j$,根据这个排序统计答案就好了。

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long lint;
const int N=100005;
struct cow
{
    lint t,d;
}c[N];
inline bool cmp(cow i,cow j)
{
    return i.t*j.d<i.d*j.t;
}
int n;lint ans,tim;
int main()
{
    scanf("%d",&n);
    for(register int i=1;i<=n;i++)scanf("%lld%lld",&c[i].t,&c[i].d);
    sort(c+1,c+n+1,cmp);
    for(register int i=1;i<=n;i++)ans+=tim*c[i].d,tim+=2*c[i].t;
    printf("%lld",ans);
}

我今天怎么好像一直都在切水题…

原文地址:https://www.cnblogs.com/yoshinow2001/p/8298642.html