POJ 2018 best cost fences (2 points)

Posted by phpform08 on Tue, 31 Dec 2019 07:26:30 +0100

Original address: http://poj.org/problem?id=2018

Question meaning: give you N numbers, let you find the maximum average value of a continuous number string, and the number of continuous number strings shall not be less than F.

Idea: bisection average value, and then for each average value, to judge whether there is a segment of subsequence length greater than L, and the average value is the largest. Then we can subtract the average value for each number, and then use the idea similar to double pointer to solve

Note: this problem seems to be a bit of a pit, there is no spj, so it can not be divided into 100 cycles

ac Code:

#include <cmath>
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <set>
#include <map>
#include <cctype>
#define eps 1e-5
#define INF 1e12
#define PI acos(-1)
#define lson l,mid,rt<<1
#define rson mid+1,r,(rt<<1)+1
#define CLR(x,y) memset((x),y,sizeof(x))
#define fuck(x) cerr << #x << "=" << x << endl

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int seed = 131;
const int maxn = 1e5 + 5;
const int mod = 998244353;
int n, f;
double a[maxn], b[maxn], sum[maxn];
bool check(double mid) {
    for (int i = 1; i <= n; i++) {
        b[i] = a[i] - mid;
        sum[i] = sum[i - 1] + b[i];
    }
    double min_val = INF;
    for (int i = f; i <= n; i++) {
        min_val = min(min_val, sum[i - f]);
        if (sum[i] - min_val >= 0) return 1;
    }
    return 0;
}
int main() {
    scanf("%d%d", &n, &f);
    for (int i = 1; i <= n; i++) scanf("%lf", &a[i]);
    double l = 0;
    double r = INF;
    while (r - l > eps) {
        double mid = (l + r) / 2;
        if (check(mid)) l = mid;
        else r = mid;
    }
    printf("%d\n", (int) (r * 1000));
    return 0;
}

Topics: less