E. Water Taps(贪心&二分)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了E. Water Taps(贪心&二分)相关的知识,希望对你有一定的参考价值。

E. Water Taps(贪心&二分)

∑ i = 1 n x i t i ∑ i = 1 n x i \\dfrac{\\sum\\limits_{i=1}^n x_it_i}{\\sum\\limits_{i=1}^n x_i} i=1nxii=1nxiti 这个函数有单调性,因为分子增大得更快。

且答案具有二分性,因为减少相同流量,温度大的下降的更快。

我们把水管按照温度排序。

所以对于当前答案 a n s ans ans,我们可以分别按顺序和逆序贪心求出最小和最大值。

T × a n s ∈ [ m i n , m a x ] T\\times ans \\in[min,max] T×ans[min,max]

时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn)

#include<bits/stdc++.h>
using namespace std;
#define f first
#define s second
#define MAX 200005
#define ll long long int
#define pii pair<ll,double>

pii t[MAX];
int n,T;

bool check(double flow){
    double x;
    double Max=0,Taken=0;
    for(int i=n;i>=1;i--) {x=min(flow-Taken,t[i].s); Max+=t[i].f*x; Taken+=x;}

    double Min=0; Taken=0;
    for(int i=1;i<=n;i++) {x=min(flow-Taken,t[i].s); Min+=t[i].f*x; Taken+=x;}
    return (Min<=T*flow && T*flow<=Max);
}

int main(){
    scanf("%d %d",&n,&T);
    double lo=0;
    double hi=0;

    for(int i=1;i<=n;i++) {scanf("%lf",&t[i].s); hi+=t[i].s;}
    for(int i=1;i<=n;i++) scanf("%I64dd",&t[i].f);

    sort(t+1,t+n+1);

    for(int i=1;i<=200;i++){
        double mid=(lo+hi)/2;

        if(check(mid)) lo=mid;
        else hi=mid;
    }
    printf("%.10lf\\n",lo);
}

思路2

先所有所有水管温度减掉 T T T,我们可以按照温度是否大于0将水管分成两组。

显然要使得和最大,绝对值求和较小的另一半全选是最优的。

然后再贪心选即可。

时间复杂度: O ( n l o g n ) O(nlogn) O(nlogn) 只有排序的复杂度。

#include<bits/stdc++.h>
using namespace std;
const int N=2e5+7;
struct node{int a,t;double s;}a[N];
int n,T;
double tmp,ans;
bool cmp(node a,node b){return a.t<b.t;}
int main()
{
	scanf("%d%d",&n,&T);
	for(int i=1;i<=n;i++)scanf("%d",&a[i].a);
	for(int i=1;i<=n;i++)scanf("%d",&a[i].t),a[i].t-=T;
	sort(a+1,a+n+1,cmp);
	if(a[1].t>0||a[n].t<0){puts("0");return 0;}
	for(int i=1;i<=n;i++)a[i].s=1.0*a[i].a*a[i].t,tmp+=a[i].s;
	if(tmp<0)
	{
		for(int i=1;i<=n;i++)a[i].t=-a[i].t,a[i].s=-a[i].s;
		reverse(a+1,a+n+1);
	}
	tmp=0;
	for(int i=1;i<=n;i++)
	{
		if(tmp+a[i].s>0){ans+=(-tmp)/a[i].t;break;}
		tmp+=a[i].s,ans+=a[i].a;
	}
	printf("%0.7lf",ans);
}

以上是关于E. Water Taps(贪心&二分)的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces 954E Water Taps

Codeforces Round #412 (rated, Div. 2, base on VK Cup 2017 Round 3) E. Prairie Partition 二分+贪心

1326. Minimum Number of Taps to Open to Water a Garden

P1084 [NOIP2012 提高组] 疫情控制(倍增&贪心&二分)

POJ 2456 Aggressive cows ( 二分 && 贪心 )

FZU 2203 单纵大法好 (二分 && 贪心)