codeforces#1300E. Water Balance(贪心)
题目链接:
https://codeforces.com/contest/1300/problem/E
题意:
给出一排水,每次操作可以使得一个区间的水变成区间水的平均值,这种操作可以执行无数次,求出字典序最小的结果
数据范围:
$1\leq a \leq 1e10$
$1\leq m \leq 1e10$
分析:
考虑子问题,如果已经有了前$i$杯水的结果,再加上一杯水应该怎么操作?
显然最优的方式是,让最后一杯水去和前面的比较,如果最后的水比前面的小,那么就与前面的合并起来
实现的时候有个巧妙的方法,对于合并好的水我们把他们看作是一个块,这样最多会有$n-1$次合并,保证了复杂度
AC代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e6+7;
int n,a[maxn],cnt,len[maxn];
double ans[maxn];
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=1;i<=n;i++){
ans[++cnt]=a[i];
len[cnt]=1;
while(cnt>1&&ans[cnt]<ans[cnt-1]){
ans[cnt-1]=(ans[cnt-1]*len[cnt-1]+ans[cnt]*len[cnt])/(len[cnt]+len[cnt-1]);
len[cnt-1]+=len[cnt];
cnt--;
}
// printf("-----------\n");
}
for(int i=1;i<=cnt;i++){
for(int j=1;j<=len[i];j++)
printf("%.12f\n",ans[i]);
}
return 0;
}

浙公网安备 33010602011771号