HDU-2993--MAX Average Problem详解

此题是关于DP的优化问题,具体解题思路贴在后面
此题大意:
读入一列正数N,a1, a2, …, aN,以及一个数F。定义ave(i,j)=ai到aj的平均值,j-i+1>=k,
求一个最大的ave(i,j)
 
首先我先把代码贴上来:
 
View Code
 1 //====================================================================
 2 //Name       :hdu 2993 MAX Average Problem
 3 //Author     :hxf
 4 //copyright  :http://blog.sina.com.cn/u/2904525152
 5 //Description:动态规划DP斜率优化
 6 //Data       :2012.7.17
 7 //========================================================================
 8 #include <iostream>
 9 #include "stdio.h"
10 #include<algorithm>
11 #define LEN 100001
12 using namespace std;
13 int temp[LEN],head,tail;//用来控制判断图上点的取舍
14 /////////////////////////////
15 int GetInt(){/////////////////这里是读入外挂(没这个这题貌似AC不掉)
16     char ch=getchar();
17     while(ch<'0'||ch>'9')ch=getchar();
18     int num=0;
19     while(ch>='0'&&ch<='9'){
20         num=num*10+ch-'0';
21         ch=getchar();
22     }
23     return num;
24 }
25 ////////////////////
26 void solve(int n,int k)
27 {
28     double sum[LEN];//用来保存部分和
29     memset(sum,0,sizeof(sum));
30     sum[0]=0;
31     for(int i=1;i<=n;i++)
32     {
33         int x=0;
34         //scanf("%d",&x);
35         x=GetInt();
36         sum[i]=sum[i-1]+x;
37     }
38     //////////////////////////////////输入完成
39     memset(temp,0,sizeof(temp));
40     temp[0]=0;head=0;tail=0;
41     double max=0;
42 //////////////////具体实现优化
43     for(int i=k;i<=n;i++)
44     {
45         int now=i-k;
46         while(head<tail)
47         {
48             double k1=(sum[temp[tail]]-sum[temp[tail-1]])/(temp[tail]-temp[tail-1]);
49             double k2=(sum[now]-sum[temp[tail]])/(now-temp[tail]);
50             if(k1>=k2)
51                 tail--;
52             else
53                 break;//去掉向上凸出来的点
54         }
55         //////////////////////////////////
56         tail++;
57         temp[tail]=now;
58 ///////////////////////////////
59         while(head<tail)
60         {
61             double k1=(sum[temp[head]]-sum[i])/(temp[head]-i);
62             double k2=(sum[temp[head+1]]-sum[i])/(temp[head+1]-i);
63             if(k1<=k2)
64                 head++;//下凸线中去掉斜率较小的点(从左往右)
65             else
66                 break;
67         }
68         double t=(sum[temp[head]]-sum[i])/(temp[head]-i);
69         if(t>max)
70             max=t;
71     }
72     printf("%.2lf\n",max);
73 }
74 int main()
75 {
76     int n=0,k=0;
77     while(scanf("%d%d",&n,&k)!=EOF)
78     {
79         solve(n,k);
80     }
81 return 0;
82 }

现在来分析解题思路:
   首先一定会设序列ai的部分和:Si=a1+a2+…+ai,,特别的定义S0=0。
   这样可以很简洁的表示出目标函数ave(i,j)=(Sj-S(i-1))/(j-(i-1))!
   如果将S函数绘在平面直角坐标系内,这就是过点Sj和点Si-1直线的斜率!
于是问题转化为:平面上已知N+1 个点,Pi(i, Si),0≤i≤N,求横向距离大
于等于F的任意两点连线的最大斜率。
 
构造下凸折线
   有序化一下,规定对i<j,只检查Pj向Pi的连线,对Pi不检查与Pj的连线。
也就是说对任意一点,仅检查该点与在其前方的点的斜率。于是我们定义点Pi
的检查集合为
Gi = {Pj, 0≤j≤i-F}
   特别的,当i<F时,Gi为空集。
   其明确的物理意义为:在平方级算法中,若要检查ave(a, b),那么一定有Pa∈Gb;
因此平方级的算法也可以这样描述,首先依次枚举Pb点,再枚举Pa∈Gb,同时检查k(PaPb)。//k为斜率
 
   若将Pi和Gi同时列出,则不妨称Pi为检查点,Gi中的元素都是Pi的被检查点。
   当我们考察一个点Pt时,朴素的平方级算法依次选取Gt中的每一个被检查点p,
考察直线pPt的斜率。但仔细观察,若集合内存在三个点Pi, Pj, Pk,且i<j<k,三个点形成如下图
所示的的关系,即Pj点在直线PiPk的上凸部分:k(Pi, Pj)>k(Pj,Pk),就很容易可以证明Pj点是多余的。


    若k(Pt, Pj) > k(Pt, Pi),那么可以看出,Pt点一定要在直线PiPj的上方,即阴
影所示的1号区域。同理若k(Pt, Pj) > k(Pt, Pk),那么Pt点一定要在直线PjPk的下
方,即阴影所示的2号区域。
 
     综合上述两种情况,若PtPj的斜率同时大于PtPi和PtPk的,Pt点一定要落在两阴影的重叠部分,
但这部分显然不满足开始时t>j 的假设。于是,Pt落在任何一个合法的位置时,PtPj的斜率要么小于PtPi,
要么小于PtPk,即不可能成为最大值,因此Pj点多余,完全可以从检查集合中删去。这个结论告诉我们,
任何一个点Pt的检查集合中,不可能存在一个对最优结果有贡献的上凸点,因此我们可以删去每一个上凸点,
剩下的则是一个下凸折线。最后需要在这个下凸折线上找一点与Pt 点构成的直线斜率最大——显然这条直
线是在与折线相切时斜率最大,如图所示。


维护下凸折线
     这一小节中,我们的目标是:用尽可能少的时间得到每一个检查点的下凸折线。
     算法首先从PF开始执行:它是检查集合非空的最左边的一个点,集合内仅有一个元素P0,
而这显然满足下凸折线的要求,接着向右不停的检查新的点:PF+1,PF+2, …, PN。
 
     检查的过程中,维护这个下凸折线:每检查一个新的点Pt,就可以向折线最右端加入一个新的点Pt-F,
同时新点的加入可能会导致折线右端的一些点变成上凸点,我们用一个类似于构造凸包的过程依次删去这些上凸点,
从而保证折线的下凸性。由于每个点仅被加入和删除一次,所以每次维护下凸折线的平摊复杂度为O(1),
即我们用O(N)的时间得到了每个检查集合的下凸折线。
 
最后的优化:利用图形的单调性
     最后一个问题就是如何求过Pt点,且与折线相切的直线了。一种直接的方法就是二分,每次查找的复杂度是O(log2N)。
但是从图形的性质上很容易得到另一种更简便更迅速的方法:
由于折线上过每一个点切线的斜率都是一定的,而且根据下凸函数斜率的单调性,如果在检查点Pt 时找到了折线上的已知一个切点A,
那么A以前的所有点都可以删除了:过这些点的切线斜率一定小于已知最优解,不会做出更大的贡献了。
     于是另外保留一个指针不回溯的向后移动以寻找切线斜率即可,平摊复杂度为为O(1)。
     至此,此题算法时空复杂度均为O(N),得到了圆满的解决。
 
呼呼,终于贴完了
本人菜鸟一个

第一次发算法的贴,实在经验不足,若是写的不好,大家多多指教哈~

特别感谢:
《浅谈数形结合思想在信息学竞赛中的应用》---周源
提供了许多关于数形结合解题的思路。
                                                                           幻o飞
                                                                         2012.7.17与凌晨2点

转载于:https://www.cnblogs.com/Free-rein/archive/2012/08/09/2630190.html

自适应控制 (Adaptive Control) 算法详解及案例分析 自适应控制是一种能够在线调整控制器参数以适应系统动态变化的控制方法。其核心思想是通过实时估计系统参数或调整控制器参数,使系统在不确定性或动态变化的环境中仍能保持稳定性和性能。 阅读详情

相关推荐

安时积分法和开路电压法结合估算锂电池SOC

基于安时积分法和开路电压法结合的锂电池SOC估计Simulink仿真建模,利用安时积分法计算放电过程中的SOC,在搁置状态利用开路电压法进行SOC修正。

qq_39304296的博客 2554

HDU2993 MAX Average Problem DP+斜率优化

题意:给定一个数字序列,定义ave(i,j)为从i到j的数字的平均值,要求j-i+1>=k,求最大的平均值。 解析:这个题可以转换一下,将sum[i]作为纵坐标的值,那么就是求相距大于k的两点之间的斜率的最大值。(参考这篇文章:)可以知道加点的时候维护一个下凸的曲线,每次找出该点和曲线的切线即在该点的最大斜率。求斜率的时候,根据下凸曲线的性质,可以删去已找到的切点之前的点。 (吐槽一下:这题很

zhj_fly的博客 299

从零开始用TS开发babylonjs - 本机环境搭建

babylonjs,初始化本地安装,web3d引擎

han3527638的专栏 795

HDU - 2993 (读入优化)

题意 给你n个数和一个数字k,要求所有长度≥k\geq k≥k的所有连续子序列中,平均值最大的值。 思路 设数组s[i]s[i]s[i]代表序列的前缀和,所求的平均值即为 s[i]−s[j]i−j(i−j≥k)\frac{s[i]-s[j]}{i-j} (i-j\geq k)i−js[i]−s[j]​(i−j≥k) 这个值即是直线s[i]=i∗k+bs[i]=i*k+bs[i]=i∗k+b的斜率。...

No cost too great! 259

RISC-V— 架构基础知识学习

蜂鸟 E200 系列是一个开源的RISC-V 处理器。蜂鸟 E200 系列由中国大陆研发团队开发,用户能够轻松与开发人员取得交流和支持。RI蜂鸟 E200 处理器研发团队拥有在国际一流公司多年开发处理器的经验,使用稳健的Verilog 2001 语法编写的可综合 RTL 代码,以工业级标准进行开发。蜂鸟 E200 的代码为人工编写,添加丰富的注释且可读性强,非常易于理解。

deilt 1万+

系统磁盘从MBR格式转换成GPT格式来升级win11

之前的《》中说到,需要把磁盘格式转化为MBR格式才能执行下去。问题是,win10升级win11要求启动方式为UEFI的话,磁盘格式不能为MBR。其实不升级也不影响啥,但是就是想好看点。所以花了点时间折腾了一下。我这是双系统,所以直接去A系统修复B系统的磁盘格式和引导。

qq_42520962的博客 9041

hdu 2993 MAX Average Problem(斜率dp)

题意:给一个长度为 n 的序列,找出长度 >= k 的平均值最大的连续子序列。 思路: 1,用一个单调队列来维护解集。 2,假设队列中从头到尾已经有元素a b c。那么当d要入队的时候,我们维护队列的上凸性质,即如果g[d,c]=g[x,y]为止,并将d点加入在该位置中。 3,求解时候,从队头开始,如果已有元素a bc,当i点要求解时,如果g[b,a] 参考博客:http://blo

A place to record sth. 437

保姆级教程:用杰理701N可视化SDK搞定ANC降噪配置(从工具到代码全流程)

本文提供了一份详细的杰理701N可视化SDK配置ANC降噪功能的教程,涵盖从开发环境搭建到代码集成的全流程。通过图形化工具和代码示例,帮助开发者快速掌握ANC参数配置技巧,优化降噪效果,解决常见问题。

weixin_30616969的博客 451

HDU 2993 MAX Average Problem(斜率优化)

题目链接:Click here~~ 题意: 给一个长度为 n 的序列,找出长度 >= k 的平均值最大的子序列。 解题思路: 斜率优化的例题。先存着代码。 #include #include #include using namespace std; const int N = 1e5 + 5; typedef long long LL; int

nyist_xiaod 3070

手把手教你 RT-DETR 添加注意力机制 | 一次性添加 20+ 种!

手把手教你 RT-DETR 添加注意力机制 | 一次性添加 20+ 种!

Coding... 2852

Codex 接入国产大模型完整指南:CC-Switch 与 Codex++ 的工程化选型

Codex 默认走 OpenAI Responses API,而 DeepSeek、GLM、Kimi 等国产模型只提供 OpenAI-compatible 的 Chat Completions——两套协议在消息结构、流式响应、reasoning 字段、tool call 上都不兼容,所以"改个 Base URL + 填国产 Key"这种朴素操作根本跑不通。本文从架构师视角出发,把 Codex 接入国产大模型这件事讲透:先剖析协议链路到底卡在哪,再对比 CC-Switch和 Codex++两套主流方案的差异

少说,多做 3855

HDU 2993 MAX Average Problem

MAX Average Problem HDU 2993 题意:给你一个长度为n的数列,求长度大于等于k的区间的最大平均值。 注意,此题卡读入。。。珍爱生命,使用fread 方法1:求斜率最大值,维护下凸 1.定义sum[i]为前缀和。每个点为(i,sum[i]) 2.求(sum[i]-sum[j])/(i-j)的最大值,即求k(i,j)的最大值。 3.在已有的下凸单调队...

WhiteAndGold的博客 286

YOLOv11改进 | Mamba-YOLOv11-L:基于SSM的高效全局建模,精度与效率的双重突破

摘要: 本文提出Mamba-YOLOv11-L,通过集成状态空间模型(SSM)改进YOLOv11的全局建模能力。针对YOLOv11在复杂场景中全局依赖缺失、精度-效率矛盾等问题,SSM以$O(N)$计算复杂度实现长程语义捕捉。改进后的模型在工业缺陷检测(Recall↑12%)、边缘设备部署(内存↓16%)、多尺度目标检测(小目标mAP↑9%)等场景表现优异,推理速度保持>40 FPS。核心创新包括轻量化SSM模块设计(稀疏状态转移+局部上下文融合)及与YOLOv11骨干的深度集成,代码实现展示了SSM

走向CTO的路上... 569

HDU 2993 MAX Average Problem (斜率优化)

HDU 2993 MAX Average Problem (斜率优化) ACM 题目地址:  HDU 2993 MAX Average Problem 题意:  给一个长度为 n 的序列,找出长度 >= k 的平均值最大的连续子序列。 分析:  斜率优化的例题。  这里有篇博客给论文里面的分析部分上色了,还不错:http://www.cnblogs.com/Free

水果君の日常 1851

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

【DP+斜率优化】 hdu2993 MAX Average Problem

MAX Average Problem 题目:http://acm.hdu.edu.cn/showproblem.php?pid=2993 题意:给一段数字序列, 求长度不小于 K 的平均值最大的子序列。 题解:不难写出dp方程dp[i]=max{(summ[i]-summ[j])/(i-j)}(j=k)。这个肯定要超时,我们要进行优化。如果我们把(i,summ[i])看成一个点就会发现求最

Ted's 游乐园 1387

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

HDU 2993 MAX Average Problem 斜率DP+IO优化

HDU 2993 给一个序列 {a[i],i∈[1,n]}\{a[i],i\in[1,n]\}{a[i],i∈[1,n]},定义子区间均值为 avg(i,j)=s[j]−s[i−1]j−i+1avg(i,j)=\dfrac{s[j]-s[i-1]}{j-i+1}avg(i,j)=j−i+1s[j]−s[i−1]​(s[i]s[i]s[i] 为 a[i]a[i]a[i] 的前缀和),并且要求子区间的...

wineandchord 260

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

HDU 2993 MAX Average Problem 斜率优化

http://acm.hdu.edu.cn/showproblem.php?pid=2993#include using namespace std; #define N 100005 double sum[N]; int n,k; int q[N],head,tail; voi

ME4546的专栏 1200

HDU-2993 MAX Average Problem

Consider a simple sequence which only contains positive integers as a1, a2 … an, and a number k. Define ave(i,j) as the average value of the sub sequence ai … aj, i<=j. Let’s calculate max(ave(i,j)...

slass-mot-odet 387

[HDU2993]MAX Average Problem

题面描述 传送门 思路 状态转移方程 Fi=max⁡(Fj,sumi−sumji−j)F_i=\max(F_j,\frac{sum_i-sum_j}{i-j})Fi​=max(Fj​,i−jsumi​−sumj​​) 决策单调性 设有j&lt;k≤i−mj&lt;k\le i-mj<k≤i−m max⁡(Fk,sumi−sumki−k)≥max⁡(Fj,sumi−sumji−...

lb2003 306

HDU 2993 MAX Average Problem【斜率优化dp】

给由n(n=k的子序列的平均值的最大值。 本题O(n^2)的dp算法比较好想,但是n的范围较大,会超时,所以,必须进行优化。这里用到的是斜率优化,《浅谈数形结合思想在信息学竞赛中的应用》这篇论文中有这一题的详细介绍。 #include #include #include #include #include using namespace std; const int maxn =

~飞呀,飞~ 1503

HDU2993——MAX Average Problem(斜率优化DP)

MAX Average Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4455    Accepted Submission(s): 1114 Problem Description Consider

JIA_char 669

【斜率优化】HDU-2993——MAX Average Problem

前言 大约一年前,我在机房学“斜率优化” 一年后的今天,我在机房学“斜率优化” ... ... 题目 Consider a simple sequence which only contains positive integers as a1, a2 ... an, and a number k. Define ave(i,j) as the average value of the s...

十里寒塘路♣烟花一半醒 381

HDU 2993 MAX Average Problem (斜率DP)

MAX Average Problem Time Limit: 2000/1000 MS (Java/Others)Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4416Accepted Submission(s): 1106 Problem Description Consider ...

anvt77205的博客 140

HDU 数形结合 2993 MAX Average Problem

MAX Average Problem Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 5613    Accepted Submission(s): 1389 Problem Description Consid

We Can 604
上一篇: HDU-2896(病毒侵袭)
下一篇: HDU-2222(Keywords Search)
badao7116
博客等级 码龄11年 0粉丝 0原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值