题解 P6243 【[USACO06OPEN]The Milk Queue G】

lmrttx

2020-12-02 21:42:11

Solution

**贪心+排序**的题目。 第一眼想到排队打水的问题,~~不止我一个吧,~~ 下面我们分析下题目。 如何决定排序顺序呢? 我们有两头牛,分别为 $x$ 与 $y$。 如果 $x$ 排在 $y$ 的前面,那么两头牛的时间之和就是 $$x.1+y.2+max(x.2,y.1)$$ 因为,$x.1$ 与 $y.2$ 是**必须耗时间去单独进行的**,而 $x.2$ 与 $y.1$ 是**同时进行**的。 同理,如果 $y$ 在 $x$ 前面,我们可知: $$y.1+x.2+max(y.2,x.1)$$ 就是时间之和。 根据这个关系排序: ```cpp struct node{ ll a,b; }cow[30000]; bool cmp(node x,node y){ return min(x.a,y.b)<min(x.b,y.a); } ``` ------------ 第一部分结束,到这里时,已经接近AC了。 从前往后循环,记录当前最大值,运用到前缀和。当然,另一种写法可以不用到前缀和,由于题解区已经有这种统计方法了,所以此处不贴。 更详细的注释见代码。 ```cpp for(register ll i=1;i<=n;i++){ sum[i]+=sum[i-1]+cow[i].a; answer=max(sum[i],answer)+cow[i].b; //answer为最终答案,由于cow[i].b的时间是必须耗的,所以直接加上。 //sum就是前缀和数组了。它可以统一前面的最优解,最后用sum更新answer就可以了。 //sum的计算和answer的更新就是我们前面介绍的贪心思想。即:cow[i].a与cow[i-1].b是同时进行的。 } ``` ------------ 好!AC代码贴上!~~我动了些手脚,您直接复制无法AC。拒绝抄袭,共建和谐洛谷!~~ ```cpp #include<bits/stdc++.h> using namespace std; typedef long long ll; ll n,answer,sum[30000]; struct node{ ll a,b; }cow[30000]; bool cmp(node x,node y){ return min(x.a,y.b)<min(x.b,y.a); } int main(){ scanf("%lld",&n); for(register ll i=1;i<=n;i++){ scanf("%lld%lld",cow[i].a,cow[i].b); } sort(cow+1,cow+n+1,cmp); for(register ll i=1;i<=n;i++){ sum[i]+=sum[i-1]+cow[i].a; answer=max(sum[i],answer)+cow[i].b; } printf("%lld",answer); return 0; } ``` 谢谢阅读,如有不足请指出qwq。