• HDU 2993 MAX Average Problem(斜率优化DP)


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2993

    题目大意:给定一个长度为n(最长为10^5)的正整数序列,求出连续的最短为k的子序列平均值的最大值。

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

    分析:斜率优化DP,要认真看

    代码如下:

     1 # include<iostream>
     2 # include<cstdio>
     3 # include<cstring>
     4 # include<algorithm>
     5 
     6 using namespace std;
     7 
     8 const int maxn = 100010;
     9 double a[maxn], sum[maxn];
    10 int n,k;
    11 int q[maxn],head,tail;
    12 
    13 //读入优化,否则超时
    14 int GetInt()
    15 {
    16     char ch=getchar();
    17     while(ch<'0' || ch>'9')
    18         ch = getchar();
    19     int num = 0;
    20     while(ch >= '0' && ch<='9')
    21     {
    22         num = num*10 + ch - '0';
    23         ch = getchar();
    24     }
    25     return num;
    26 }
    27 
    28 void DP()
    29 {
    30     head = tail =0;
    31     double ans = -1;
    32     for(int i=k; i<=n; i++)
    33     {
    34         int j = i-k;
    35         //维护下凸
    36         while(tail - head >=2)
    37         {
    38             double x1 = j - q[tail-1];
    39             double y1 = sum[j] - sum[q[tail-1]];
    40             double x2 = q[tail-1] - q[tail-2];
    41             double y2 = sum[q[tail-1]] - sum[q[tail-2]];
    42             if(x1 * y2 - y1 *x2 >= 0)
    43                 tail--;
    44             else
    45                 break;
    46         }
    47         q[tail++] = j;
    48         //寻找最优解并删除无用元素
    49         while(tail - head >=2)
    50         {
    51             double x1 = i - q[head];
    52             double y1 = sum[i] - sum[q[head]];
    53             double x2 = i - q[head+1];
    54             double y2 = sum[i] - sum[q[head+1]];
    55             if(x1*y2 - y1*x2 >= 0)
    56                 head ++;
    57             else
    58                 break;
    59         }
    60         double tmp = (sum[i] - sum[q[head]])/(i-q[head]);
    61         ans = max(ans, tmp);
    62     }
    63     printf("%.2lf
    ",ans);
    64 }
    65 
    66 int main()
    67 {
    68     //freopen("in.txt","r",stdin);
    69     while(scanf("%d%d",&n,&k)!=EOF)
    70     {
    71         sum[0] = 0;
    72         for(int i=1; i<=n; i++)
    73         {
    74             a[i] = GetInt();
    75             sum[i] = sum[i-1] + a[i];
    76         }
    77         DP();
    78     }
    79     return 0;
    80 }
  • 相关阅读:
    【css】用纯 CSS 判断鼠标进入的方向
    【window】系统禁止运行脚本
    【go】VSCode配置Go插件和debug设置
    【PHP】php之Trait详解
    【layui】laydata 自定义日期之外格式的处理办法
    【PHP】防止视频资源被下载的解决办法
    【Markdown】 编辑器Editor.md集成使用
    代码之间为什么要加空格?
    求求你,别问了,Java字符串是不可变的
    养生吧,程序员!
  • 原文地址:https://www.cnblogs.com/acm-bingzi/p/3334058.html
Copyright © 2020-2023  润新知