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=1∑nxii=1∑nxiti 这个函数有单调性,因为分子增大得更快。
且答案具有二分性,因为减少相同流量,温度大的下降的更快。
我们把水管按照温度排序。
所以对于当前答案 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 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 提高组] 疫情控制(倍增&贪心&二分)