题目 | Average and Median
AtCoder Beginner Contest 236
E - Average and Median
https://atcoder.jp/contests/abc236/tasks/abc236_e
Time Limit: 2 sec / Memory Limit: 1024 MB
Score :
Problem Statement
We have
Takahashi will choose any number of cards from these. However, for each
Find the following values.
- The maximum possible average of the integers written on the chosen cards
- The maximum possible median of the integers written on the chosen cards
Here, the median of the
Constraints
- All values in input are integers.
Input
Input is given from Standard Input in the following format:
Output
Print two lines. The first and second lines should contain the maximum possible average and maximum possible median of the integers written on the chosen cards, respectively. For the average, your output will be considered correct when its relative or absolute error from the exact answer is at most
Sample Input 1
6
2 1 2 1 1 10
Sample Output 1
4
2
Choosing the
Choosing the
Sample Input 2
7
3 1 4 1 5 9 2
Sample Output 2
5.250000000
4
For the average, your output may contain some degree of error: for example, the output
我的笔记
用二分转化问题
可将“平均数(中位数)是什么?”这个问题转化为“平均数(中位数)是否大于
平均数是否大于
令
中位数是否大于
若
用动态规划选择卡片
可以看到,我们将问题转化后,这两个问题都需要对
创建两个数组:
可以建立递推关系:
分析下递推关系,先看
时间复杂度为
源码
#include <bits/stdc++.h>
#define SIZE 100010
#define esp 1e-4
using namespace std;
int N;
int A[SIZE];
int main(void)
{
ios::sync_with_stdio(false);
cin >> N;
for (int i = 1; i <= N; i++)
{
cin >> A[i];
}
double l1 = 1, r1 = 1e9;
while (r1 - l1 > esp)
{
double mid = (l1 + r1) / 2;
double f[SIZE], g[SIZE];
f[0] = g[0] = 0;
for (int i = 1; i <= N; i++)
{
f[i] = max(f[i - 1], g[i - 1]) + A[i] - mid;
g[i] = f[i - 1];
}
if (max(f[N], g[N]) >= 0)
{
l1 = mid;
}
else
{
r1 = mid;
}
}
cout << l1 << endl;
int l2 = 1, r2 = 1e9;
while (l2 < r2)
{
int mid = (l2 + r2 + 1) / 2;
int f[SIZE], g[SIZE];
f[0] = g[0] = 0;
for (int i = 1; i <= N; i++)
{
f[i] = max(f[i - 1], g[i - 1]) + ((A[i] >= mid) ? 1 : -1);
g[i] = f[i - 1];
}
if (max(f[N], g[N]) > 0)
{
l2 = mid;
}
else
{
r2 = mid - 1;
}
}
cout << l2 << endl;
return 0;
}
补题时出现的错误
平均数可能为小数,因此需要实数范围的二分。二分判断条件为 max(f[N], g[N]) >= 0
,因为是实数范围的二分,所以改成 max(f[N], g[N]) > 0
也能过。
中位数为整数,因此用整数二分,这里出错了。首先是 mid = (l2 + r2 + 1) / 2
,因为这个二分相当于查找的是满足条件的最大的一个数,因此是需要加一的。其次是判断条件 max(f[N], g[N]) > 0
,这个二分要找满足该条件的最大的数,其实就是要找等于零的情况,最开始我带了等号,答案就会变大了。
本文采用 CC BY-SA 4.0 许可,本文 Markdown 源码:Haotian-BiJi