POJ 2018 Best Cow Fences(二分答案)

POJ 2018 Best Cow Fences(二分答案)

Best Cow Fences
Time Limit: 1000MS Memory Limit: 30000K
Total Submissions: 12144 Accepted: 3958
Description

Farmer John‘s farm consists of a long row of N (1 <= N <= >100,000)fields. Each field contains a certain number of cows, >1 <= ncows <= 2000.

FJ wants to build a fence around a contiguous group of these >fields in order to maximize the average number of cows per >field within that block. The block must contain at least F (1 ><= F <= N) fields, where F given as input.

Calculate the fence placement that maximizes the average, >given the constraint.
Input

  • Line 1: Two space-separated integers, N and F.
  • Lines 2..N+1: Each line contains a single integer, the >number of cows in a field. Line 2 gives the number of cows in >field 1,line 3 gives the number in field 2, and so on.
    Output
  • Line 1: A single integer that is 1000 times the maximal >average.Do not perform rounding, just print the integer that >is 1000*ncows/nfields.
    Sample Input

10 6
6
4
2
10
3
8
5
9
4
1
Sample Output

6500


题意: N, F。n个数,求一个长度大于F的序列,平均数最大。输出平均数乘1000


思路: 二分答案,对于【L,R】区间中的mid,求是否有一个长度大于F的序列平均数大于mid.来缩小区间

把序列减去mid,问题就变成了是否存在一个长度大于F的序列,最大字段和大于零。没有长度限制,最大子段和的DP问题。有了长度限制可以转化为前缀和sum[r] - sum[l - 1] ,我们用前缀和维护一个长度大于F的序列,维护一下前缀和的最小值。

    double ans = -1e9;
    double min_val = 1e9;
    for(int i = L; i <= N; i++ ) {
        min_val = min(min_val, sum[i - L]);
        ans = max(ans, sum[i] - min_val);
    }
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <iostream>
#include <vector>

using namespace std;
const int MAXN = 1e5 + 7;
const double EPS = 1e-5;

int N, L;

double a[MAXN], b[MAXN], sum[MAXN];

int main()
{
    while(~scanf("%d %d", &N, &L)) {
        for(int i = 1; i <= N;i ++ ) {
            scanf("%lf", &a[i]);
        }
        double l = -1e8, r = 1e8;
        while(l + EPS < r) {
            double mid = (l + r) / 2.0;
            for(int i = 1; i <= N; i++ ) {
                b[i] = a[i] - mid;
            }
            for(int i = 1; i <= N; i++ ) {
                sum[i] = (sum[i - 1] + b[i]);
            }
            double ans = -1e9;
            double min_val = 1e9;
            for(int i = L; i <= N; i++ ) {
                min_val = min(min_val, sum[i - L]);
                ans = max(ans, sum[i] - min_val);
            }
            if(ans >= 0) {
                l = mid;
            } else {
                r = mid;
            }
        }
        printf("%d\n", int(r * 1000));
    }
    return 0;
}

原文地址:https://www.cnblogs.com/Q1143316492/p/9107546.html

时间: 2024-11-07 16:36:18

POJ 2018 Best Cow Fences(二分答案)的相关文章

POJ 2018 Best Cow Fences

斜率优化DP...<浅谈数形结合思想在信息学竞赛中的应用 安徽省芜湖一中 周源>例题... Best Cow Fences Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 9311   Accepted: 2986 Description Farmer John's farm consists of a long row of N (1 <= N <= 100,000)fields. Each field c

POJ2018 Best Cow Fences 二分答案/DP

显然二分答案,然后减去对应的mid,求超过L的最大子段和验证就好了. 当然记录下长度的直接DP也是可以的. 然而二分答案怎么都WA,很好奇为什么 直接输出r反而是能过的. 看了下https://blog.csdn.net/jiangshibiao/article/details/21963437 想起来double取整输出的时候要加上eps 1 https://blog.csdn.net/jiangshibiao/article/details/21963437 原文地址:https://www

POJ 2018 Best Cow Fences(二分最大区间平均数)题解

题意:给出长度>=f的最大连续区间平均数 思路:二分这个平均数,然后O(n)判断是否可行,再调整l,r.判断方法是,先求出每个数对这个平均数的贡献,再求出长度>=f的最大贡献的区间,如果这个最大贡献大于0说明这个二分出来的数可行. 代码: #include<set> #include<map> #include<stack> #include<cmath> #include<queue> #include<vector>

POJ 3662 Telephone Lines(二分答案+SPFA)

[题目链接] http://poj.org/problem?id=3662 [题目大意] 给出点,给出两点之间连线的长度,有k次免费连线, 要求从起点连到终点,所用的费用为免费连线外的最长的长度. 求最小费用. [题解] 二分答案,对于大于二分答案的边权置为1,小于等于的置为0, 则最短路就是超出二分答案的线数,如果小于等于k,则答案是合法的 [代码] #include <cstdio> #include <cstring> using namespace std; const i

poj 2349 Arctic Network MST/二分答案

poj 2349 Arctic Network 题目传送 Sol: 方法一: 贪心的想,发现n个点只需要n-1条边即可,求MST即可,再把MST中最大的m-1条边去掉,第m大就是答案. code: #include<string> #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> #define IL inline #define RG register

POJ 3273 Monthly Expense 【二分答案】

题意:给出n天的花费,需要将这n天的花费分成m组,使得每份的和尽量小,求出这个最小的和 看题目看了好久不懂题意,最后还是看了题解 二分答案,上界为这n天花费的总和,下界为这n天里面花费最多的那一天 如果mid>=m,说明mid偏小,l=mid+1, 如果mid<m,说明mid偏大,r=mid, 1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include <cmath>

poj 动态规划DP - 2018 Best Cow Fences

这道题目我一开始的思路是用二维DP,结果TLE了.后来换了个思路,终于AC了. 不需要判断所有的情况,我们用dp[i]表示前i个牛圈中最大的牛数,而这个i首先必须>=限制的牛圈树f.用num[i]表示dp[i]中包含了多少牛圈. 我们可以知道,dp[i] = sum[i] - sum[i-f])/f  or  dp[i-1] + data[i], 前一个代表到i为止前f个牛圈的牛数,后一个代表前i-1个牛圈中最大牛数+第i个牛圈中的牛数.其实也就是到i为止前num[i-1]+1个牛圈的牛数.而判

POJ 3111 K Best(二分答案)

[题目链接] http://poj.org/problem?id=3111 [题目大意] 选取k个物品,最大化sum(ai)/sum(bi) [题解] 如果答案是x,那么有sigma(a)>=sigma(b*x) 至于选取,就可以根据a-b*x排序,贪心选取即可. 对于输出物品的id,因为在不断逼近结果的过程中,排序的结果也不断在调整 所以我们最后的得到的排序结果的前k个就是答案. [代码] #include <cstdio> #include <algorithm> usi

POJ 2749 Building roads 2-sat+二分答案

把爱恨和最大距离视为限制条件,可以知道,最大距离和限制条件多少具有单调性 所以可以二分最大距离,加边+check 1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<vector> 5 #include<stack> 6 #define N 5010 7 #define INF 4000000 8 using namespace std; 9 int di