AtCoder Beginner Contest 236 E - Average and Median

时间:2022-01-24
本文章向大家介绍 AtCoder Beginner Contest 236 E - Average and Median,主要包括 AtCoder Beginner Contest 236 E - Average and Median使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

E - Average and Median

E - Average and Median (atcoder.jp)

题目大意:给你n个数,在其中选数字,要求每相邻的两个数至少需要选其中一个,求出最大的平均数和中位数,此处的中位数定义为第\(\lceil \frac{n}{2} \rceil\)小的数字

思路:

首先,求大于k的平均数可以转化为求m,且m满足每一项减m后,各项之和≥0,而最大的m即为我们所求的最大的平均数k。求该题目中的最大中位数k可以转化为求m,且m满足比m大的数字个数大于比m小的数字个数,而最大的m一定能保证是中位数,同时也是最大的中位数k

而求m的过程可以用二分答案 + DP

设f[i] 表示选第i项时,前i项中所有被选的项的最大和

我们二分枚举求平均数是需要用到实数域二分,可以用for循环也可以用while(r - l > eps)

然后把每一项减去mid,二分的判断条件是此时最大和是否大于等于0

二分枚举求中位数,需要判断序列每一项,如果该项大于等于mid,则为1,否则为-1

二分的判断条件也是此时最大和是否大于等于0

代码示例:

//#pragma comment(linker,   "/STACK:10240000000000,10240000000000")
//#pragma GCC optimize(2)

#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for (int i=(a);i<=(b);++i)
#define endl '\n'
#define IOS ios::sync_with_stdio(0); cin.tie(0);
#define lowbit(x) x & (-x)
#define clr(x) memset(x, 0, sizeof(x));
#define fi first
#define se second
typedef vector<int> vii;
typedef vector<long long> vll;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const pii moves[] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
ll ksm(ll a, ll b, ll p) {if (b == 0) return 1; ll ns = ksm(a, b >> 1, p); ns = ns * ns % p; if (b & 1) ns = ns * a % p; return ns;}
inline int read()
{
    int x = 0, w = 0; char ch = getchar();
    while(ch < '0' || ch > '9'){w |= ch == '-';ch = getchar();}
    while(ch >= '0' && ch <= '9'){x = (x << 3) + (x << 1) + ch - '0';ch = getchar();}
    return w ? -x : x;
}		
const int MAXN = 0x7fffffff;

int main ()
{	
	//IOS;
	int n;
	cin >> n;
	vii a(n);
	for (int i = 0; i < n; i ++) cin >> a[i];
{
	double l = 0, r = 1e9;
	double mid;
	for(int i = 1; i <= 1000; i ++)
	{
		mid = (l + r) / 2;
		vector<double> f(n + 5, 0);
		f[0] = a[0] - mid;
		for(int i = 1; i < n; i ++)
		{
			if(i < 2) f[i] = max(f[i], f[i - 1]) + a[i] - mid;
			if(i > 1) f[i] = max(f[i - 1], f[i -  2]) + a[i] - mid;
		}	
		if(max(f[n - 1], f[n - 2]) >= 0) l = mid;
		else r = mid;
	}
	cout << fixed << setprecision(10) << l << endl;
}		
{
	int l = 0, r = 1e9;
	while(l < r)
	{
		double mid = (l + r + 1) / 2;
		vii f(n + 5, -1e9);
		for (int i = 0; i < n; i ++)
		{
			if(i < 2) f[i] = 0;
			if(i > 0) f[i] = max(f[i], f[i - 1]);
			if(i > 1) f[i] = max(f[i], f[i - 2]);
			f[i] += a[i] >= mid ? 1 : -1;
		}
		if(max(f[n - 2], f[n - 1]) > 0) l = mid;
		else r = mid - 1;
	}
	cout << l << endl;
}
	return 0;
}	
/*

*/	

原文地址:https://www.cnblogs.com/yramvj/p/15840834.html