洛谷 P2878 [USACO07JAN]保护花朵Protecting the Flowers 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置。

题目链接:https://www.luogu.org/problem/show?pid=2878

(本来想放bzoj的链接  然而bzoj这道题挂了)

【题目描述】

约翰留下他的N(N<=100000)只奶牛上山采木.他离开的时候,她们像往常一样悠闲地在草场里吃草.可是,当他回来的时候,他看到了一幕惨剧:牛们正躲在他的花园里,啃食着他心爱的美丽花朵!为了使接下来花朵的损失最小,约翰赶紧采取行动,把牛们送回牛棚. 牛们从1到N编号.第i只牛所在的位置距离牛棚Ti(1≤Ti≤2000000)分钟的路程,而在约翰开始送她回牛棚之前,她每分钟会啃食Di(1≤Di≤100)朵鲜花.无论多么努力,约翰一次只能送一只牛回棚.而运送第第i只牛事实上需要2Ti分钟,因为来回都需要时间.    写一个程序来决定约翰运送奶牛的顺序,使最终被吞食的花朵数量最小.

【输入格式】

第1行输入N,之后N行每行输入两个整数Ti和Di

【输出格式】

一个整数,表示最小数量的花朵被吞食

【样例输入】

6

3 1

2 5

2 3

3 2

4 1

1 6

【样例输出】

86

【样例解释】

约翰用6,2,3,4,1,5的顺序来运送他的奶牛

这题做的时候是hzwer神犇出的模考题,然后错得一塌糊涂qwq

分析:

这题用贪心来做。

单独看牛群中的两头牛a、b,每头牛拥有两个参数D和T。

假设这两头牛是相邻的,a在b之后被带走,考虑将这两头牛交换顺序,不会影响牛群中其他牛吃花的时间。

交换顺序前 吃花数量:2*T[b]*D[a]

交换顺序后 吃花数量:2*T[a]*D[b]

要使这次交换顺序是有效的,也就是说交换后的吃花数量减少了

则应满足 T[b]*D[a] > T[a]*D[b]

化简可得  D[a]/T[a] > D[b]/T[b]

推理可知,当一头牛的【吃花数量/带走时间】越大时,它应该先被带走。

简单理解的话也可以认为是先把腿长而且能吃的奶牛带走吧...(逃)

AC代码:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<queue>
 6
 7 using namespace std;
 8 const int MAXN = 100005;
 9
10 struct cow
11 {
12     int t,d;
13     double jud;
14 }a[MAXN];//存储奶牛的相关参数
15
16 long long sum[MAXN];
17
18 bool cmp(cow a,cow b)
19 {
20     return a.jud > b.jud?1:0;
21 }//根据比值来比较结构体大小
22
23 int main()
24 {
25     int n;
26     scanf("%d",&n);
27     for(int i = 0;i < n;++ i)
28     {
29         scanf("%d%d",&a[i].t,&a[i].d);
30         a[i].jud = (double) a[i].d/a[i].t;
31     }
32     sort(a,a+n,cmp);
33
34     sum[n-1] = (long long)a[n-1].d;
35     for(int i = n-1;i >= 0;i --)
36         sum[i] = (long long)a[i].d + sum[i+1];
37     //计算剩余的i头奶牛每分钟吃掉的花朵
38     long long ans = 0;
39     for(int i = 0;i < n;i ++)
40     {
41         ans += (long long)2 * a[i].t * sum[i+1];
42     }
43     printf("%lld",ans);
44     return 0;
45 }

保护花朵 代码

大佬说最好用乘法,直观快速而且不用考虑精度。

……窝就是喜欢用除法嘛……窝就是觉得这样方便……

QAQ于是下面附上乘法的代码,@WZY大佬

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstdlib>
 4 #include <cstring>
 5 #include <algorithm>
 6 #include <vector>
 7 #include <queue>
 8 inline void read(long long &x)
 9 {
10     x = 0;char ch = getchar();char c = ch;
11     while(ch > ‘9‘ || ch < ‘0‘)c = ch, ch = getchar();
12     while(ch <= ‘9‘ && ch >= ‘0‘)x = x * 10 + ch - ‘0‘,ch = getchar();
13     if(c == ‘-‘)x = -x;
14 }
15 const long long MAXN = 1000000 + 10;
16 const int INF = 0x3f3f3f3f;
17
18 long long n,T[MAXN],D[MAXN],cnt[MAXN];
19
20 bool cmp(long long a, long long b)
21 {
22     return D[a] * T[b] > D[b] * T[a];
23 }//直接根据乘法结果排序
24
25 long long ans;
26 long long sum;
27
28 int main()
29 {
30 //    freopen("data.txt", "r", stdin);
31     read(n);
32     for(register long long i = 1;i <= n;++ i)
33     {
34         read(T[i]);read(D[i]);
35         cnt[i] = i;
36         sum += D[i];
37     }
38     std::sort(cnt + 1, cnt + 1 + n, cmp);
39     for(register long long i = 1;i <= n;++ i)
40     {
41         sum -= D[cnt[i]];
42         ans += ((long long)(sum * T[cnt[i]]) << 1);
43     }
44     printf("%lld", ans);
45     return 0;
46 }

保护花朵 by嘒彼小星

或许这就是大佬吧

时间: 2024-08-16 06:55:31

洛谷 P2878 [USACO07JAN]保护花朵Protecting the Flowers 题解的相关文章

洛谷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

P2878 [USACO07JAN]保护花朵Protecting the Flowers - 贪心

传送门 思路: 对于"找出一种最优排列顺序,使答案最优"的贪心题目,我们可以用"邻项交换"的方法去找出并证明贪心策略. 例如本题,我们假设有两头奶牛,其到达牛圈时间分别为Ti,Ti+1,每分钟吃掉的花朵数分别为Di,Di+1. 有两种情况: ① 排列顺序为i  i+1 则两头牛吃掉的花朵数为 res1=2TiDi+1 ② 排列顺序为i+1  i 则两头牛吃掉的花朵数为 res2=2Ti+1Di 假设前一种方案是最优解,则res1<res2,即TiDi+1<

USACO 保护花朵 Protecting the Flowers, 2007 Jan

Description 约翰留下了 N 只奶牛呆在家里,自顾自地去干活了,这是非常失策的.他还在的时候,奶牛像 往常一样悠闲地在牧场里吃草.可是当他回来的时候,他看到了一幕惨剧:他的奶牛跑进了他的花园, 正在啃食他精心培育的花朵!约翰要立即采取行动,挨个把它们全部关回牛棚. 约翰牵走第 i 头奶牛需要 T i 分钟,因为要算来回时间,所以他实际需要 2 · T i 分钟.第 i 头奶牛 如果还在花园里逍遥,每分钟会啃食 Di 朵鲜花.但只要约翰抓住了它,开始牵走它的那刻开始,就 没法吃花了.请帮

洛谷P2879 [USACO07JAN]区间统计Tallest Cow

To 洛谷.2879 区间统计 题目描述 FJ's N (1 ≤ N ≤ 10,000) cows conveniently indexed 1..N are standing in a line. Each cow has a positive integer height (which is a bit of secret). You are told only the height H (1 ≤ H ≤ 1,000,000) of the tallest cow along with th

洛谷 P2879 [USACO07JAN]区间统计Tallest Cow 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:https://www.luogu.org/problem/show?pid=2879 题目描述 FJ's N (1 ≤ N ≤ 10,000) cows conveniently indexed 1..N are standing in a line. Each cow has a positive integer height (which is a bit of secret). You are told on

洛谷—— P2880 [USACO07JAN]平衡的阵容Balanced Lineup

https://www.luogu.org/problemnew/show/P2880 题目背景 题目描述: 每天,农夫 John 的N(1 <= N <= 50,000)头牛总是按同一序列排队. 有一天, John 决定让一些牛们玩一场飞盘比赛. 他准备找一群在对列中为置连续的牛来进行比赛. 但是为了避免水平悬殊,牛的身高不应该相差太大. John 准备了Q (1 <= Q <= 180,000) 个可能的牛的选择和所有牛的身高 (1 <= 身高 <= 1,000,0

洛谷 P2879 [USACO07JAN]区间统计Tallest Cow

传送门 题目大意: n头牛,其中最高身高为h,给出r对关系(x,y) 表示x能看到y,当且仅当y>=x并且x和y中间的牛都比 他们矮的时候,求每头牛的最高身高. 题解:贪心+差分 将每头牛一开始都设为最高高度. 每一对关系(x,y),我们将[x+1,y-1]这个区间的身高变为 min(x,y)-1.这样是不对了.因为要维护[x+1,y-1]这个区间里 各个元素的大小关系,所以要将[x+1,y-1]的元素身高都减1. 一开始我是用线段树做的,后来发现题解用的差分. 没有询问的区间修改,差分做就好了

洛谷 P3376 【模板】网络最大流 题解

此文为博主原创题解,转载时请通知博主,并把原文链接放在正文醒目位置. 题目链接:https://www.luogu.org/problemnew/show/3376 题目描述 如题,给出一个网络图,以及其源点和汇点,求出其网络最大流. 输入输出格式 输入格式: 第一行包含四个正整数N.M.S.T,分别表示点的个数.有向边的个数.源点序号.汇点序号. 接下来M行每行包含三个正整数ui.vi.wi,表示第i条有向边从ui出发,到达vi,边权为wi(即该边最大流量为wi) 输出格式: 一行,包含一个正

洛谷P1789【Mc生存】插火把 题解

题目传送门 这道题目可以纯暴力: #include<bits/stdc++.h> //Minecraft 666 using namespace std; int a[110][110]; int n,m,k,ans; int main(){ scanf("%d%d%d",&n,&m,&k); for(int i=1;i<=m;i++){ int x,y; scanf("%d%d",&x,&y); a[x-2