zoukankan      html  css  js  c++  java
  • POJ2018 Best Cow Fences —— 斜率优化DP

    题目链接:https://vjudge.net/problem/POJ-2018

    Best Cow Fences
    Time Limit: 1000MS   Memory Limit: 30000K
    Total Submissions: 11394   Accepted: 3736

    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
    

    Source

    题意:

    给出一个序列,求一段个数大于等于F的子序列,使得它的(和/个数)最大。

    题解:

    1.最暴力的做法是:先求出前缀和,再枚举序列的起点终点。时间复杂度为O(n^2),因此不能通过。

    2.我们可以把前缀和sum[i]看作是坐标轴的y坐标,个数i看作是坐标轴的x坐标。这样就转化为求:(sum[i]-sum[j])/(i-j)最大,显然这是一个斜率的表达式,因而要求的是最大斜率。

    3.根据第2点,我们可以用斜率进行优化:由于求的是最大斜率,因而备选点要维持下凸性。

    4.关于每组的个数最少为F的处理,详情在:HDU3045 Picnic Cows 

    代码如下:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <algorithm>
     5 #include <vector>
     6 #include <cmath>
     7 #include <queue>
     8 #include <stack>
     9 #include <map>
    10 #include <string>
    11 #include <set>
    12 using namespace std;
    13 typedef long long LL;
    14 const int INF = 2e9;
    15 const LL LNF = 9e18;
    16 const int mod = 1e9+7;
    17 const int MAXM = 1e5+10;
    18 const int MAXN = 1e5+10;
    19 
    20 double sum[MAXN], dp[MAXN];
    21 int head, tail, q[MAXN];
    22 
    23 double slope(int i, int j)  //斜率
    24 {
    25     return (sum[j]-sum[i])/(j-i);
    26 }
    27 
    28 int main()
    29 {
    30     int n, F;
    31     while(scanf("%d%d",&n,&F)!=EOF)
    32     {
    33         sum[0] = 0;
    34         for(int i = 1; i<=n; i++)
    35         {
    36             int val;
    37             scanf("%d", &val);
    38             sum[i] = sum[i-1] + val;
    39         }
    40 
    41         double ans = 0;
    42         head = tail = 0;
    43         q[tail++] = 0;
    44         for(int i = F; i<=n; i++)
    45         {
    46             while(head+1<tail && slope(q[head],i)<slope(q[head+1], i))  head++;
    47             ans = max(ans, slope(q[head],i));
    48 
    49             int j = i-F+1;  //不能直接放i,因为要求了每一组至少为F,故i不能为i+1转移。
    50             while(head+1<tail && slope(q[tail-1], j)<slope(q[tail-2],q[tail-1])) tail--;
    51             q[tail++] = j;
    52         }
    53 
    54         printf("%d
    ", (int)(ans*1000));
    55     }
    56 }
    View Code
  • 相关阅读:
    二进制数组
    model模块
    Decorator [ˈdekəreɪtə(r)] 修饰器/装饰器 -- 装饰模式
    箭头函数
    async [ə'zɪŋk] 函数
    cocos2d-x 事件分发机制 ——触摸事件监听
    算法:高速排序
    [zlib]_[0基础]_[使用Zlib完整解压zip内容]
    设计模式之状态模式(State)摘录
    编写Web Serviceclient訪问www.webxml.com.cn提供的服务
  • 原文地址:https://www.cnblogs.com/DOLFAMINGO/p/8207520.html
Copyright © 2011-2022 走看看