题解 | #[USACO 2007 Jan S]Protecting the Flowers#

[USACO 2007 Jan S]Protecting the Flowers

https://ac.nowcoder.com/acm/problem/25043

这道题算是我的贪心入门了,题意大概就是n头牛,农夫要送他们回牛舍,送一只牛回去要ti时间(注意这里是单程的,回来也要Ti),送牛的时候其他牛会在原地吃花,每头牛每单位吃Di朵花,问怎样送牛花被吃得最少。(注意每头牛的Ti,Di都不相同)(如果这个题解对你有用请点点赞鼓励鼓励我哈,谢谢)

思路:

1、其实这题影响的因素就两个,Ti和Di,我们设想两头牛AB,是先送A再送B好还是先送B再送A好,无论先送谁,其实都不影响前面跟后面的牛吃的花数,只会影响AB吃的花数。我们设想:AB优于BA(谁优都可以)

2、设前面的牛被送的时间为X,来回就为2X。

对AB而言: 牛A:吃的花为2X*DA -------- 牛B:吃的花为(2X+Ta)*Db(因为B前面多了个A)

对BA而言: 牛B:吃的花为2X*DB -------- 牛A:吃的花为(2X+Tb)*DA 得出如此式子

3、得出式子后因为要让花吃的尽可能少所以我们不是单笔一只牛,而是两只牛加起来一起比,因为设想的是AB优于BA所以2X*DA+(2X+Ta)Db < 2XDB+(2X+Tb)*DA,化解得出应该为 Ta/Da < Tb/Db;得出这个公式就已经解出最核心的问题了,就是我们应该排序,把牛牛按照Ti/Di结果小的排前面的规则进行排序

4、按照排序后把每只猪要等待的时间算出来,再算出他吃的花的数量进行累加,最后的出答案,下面是完整代码

#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
struct cow{
    int ti;
    int di;
}a[100005];
int cmp(cow x,cow y){
    return (float)x.ti/x.di < (float)y.ti/y.di; //这里要转为浮点型,不然排序排不准噢
}
int main(){
    IOS;
    int n;cin>>n;
    b[0]=0;
    for(int i=1;i<=n;i++){
        cin>>a[i].ti;
        cin>>a[i].di;
    }
    sort(a+1,a+n+1,cmp);
//     for(int i=1;i<=n;i++){
//         cout<<a[i].ti<<" "<<a[i].di<<endl;
//     }
    long long num=0,sum=0;
    for(int i=2;i<=n;i++){
        num+=(a[i-1].ti);   //num是计算农夫走路的时间(x2就是下一只猪吃花的时间)
        sum+=2*num*a[i].di;  //算出每一只猪吃的时间并且累加,得到最终结果
//         cout<<num<<" "<<sum<<endl;
    }
    cout<<sum;
    return 0;
}
全部评论

相关推荐

点赞 评论 收藏
转发
点赞 收藏 评论
分享
牛客网
牛客企业服务