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): 5855    Accepted Submission(s): 1456

Problem Description

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)), 1<=i<=j-k+1<=n.

Input

There multiple test cases in the input, each test case contains two lines.

The first line has two integers, N and k (k<=N<=10^5).

The second line has N integers, a1, a2 ... an. All numbers are ranged in [1, 2000].

Output

For every test case, output one single line contains a real number, which is mentioned in the description, accurate to 0.01.

Sample Input

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

Sample Output

6.50

Source

2009 Multi-University Training Contest 19 - Host by BNU

题意:

即求一段长度大于等于K且平均值最大的子串的平均值。

思路:

斜率优化入门题,推荐04年国家集训队周源的论文(这题为例题讲解),子串s+1到t的平均值为(sum[t]-sum[s])/(t-s);这个可以看做直线的斜率,根据它具有的性质来优化,具体见论文。

注意算斜率尽量用乘法算。

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#pragma comment (linker,"/STACK:102400000,102400000")
#define maxn 100005
#define MAXN 200005
#define mod 1000000009
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-6
typedef long long ll;
using namespace std;

int n,m,ans,cnt,tot,flag;
int a[maxn],sum[maxn];
int q[maxn];
double res;

void solve()
{
    int i,j,t,cur;
    int head=0,tail=-1;
    double pre,dx1,dy1,dx2,dy2;
    res=0;
    for(i=m; i<=n; i++)
    {
        cur=i-m;
        while(head<tail)
        {
            dy1=sum[cur]-sum[q[tail]]; dx1=cur-q[tail];
            dy2=sum[q[tail]]-sum[q[tail-1]]; dx2=q[tail]-q[tail-1];
            if(dy1*dx2<=dx1*dy2) tail--;
            else break ;
        }
        q[++tail]=cur;
        while(head<tail)
        {
            dy1=sum[i]-sum[q[head]];  dx1=i-q[head];
            dy2=sum[i]-sum[q[head+1]]; dx2=i-q[head+1];
            if(dy1*dx2<=dx1*dy2) head++;
            else break ;
        }
        res=max(res,(sum[i]-sum[q[head]]+0.0)/(i-q[head]+0.0)); // 不能写dy1/dx1 上一个循环可能不进入
    }
    printf("%.2f\n",res);
}
int main()
{
    int i,j,t;
    while(~scanf("%d%d",&n,&m))
    {
        sum[0]=0;
        for(i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
            sum[i]=sum[i-1]+a[i];
        }
        solve();
    }
    return 0;
}

hdu 2993 MAX Average Problem (斜率优化dp入门),布布扣,bubuko.com

时间: 2024-10-06 14:46:39

hdu 2993 MAX Average Problem (斜率优化dp入门)的相关文章

hdu 2993 MAX Average Problem(斜率DP入门题)

题目链接:hdu 2993 MAX Average Problem 题意: 给一个长度为 n 的序列,找出长度 >= k 的平均值最大的连续子序列. 题解: 这题是论文的原题,请参照2004集训队论文<周源--浅谈数形结合思想在信息学竞赛中的应用> 这题输入有点大,要加读入优化才能过. 1 #include<bits/stdc++.h> 2 #define F(i,a,b) for(int i=a;i<=b;++i) 3 using namespace std; 4 5

HDU 2993 MAX Average Problem(斜率优化)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2993 Problem Description 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

HDU 2993 MAX Average Problem(斜率DP经典+输入输出外挂)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2993 题目大意:给出n,k,给定一个长度为n的序列,从其中找连续的长度大于等于k的子序列使得子序列中的平均值最小. 解题思路:斜率DP经典题, 详细分析见: NOI2004年周源的论文<浅谈数形结合思想在信息学竞赛中的应用> 还有要注意要用输入输出外挂,不是getchar()版的,是fread()版的,第一次遇到这么变态的题目- -|||. 代码: 1 #include<iostream&g

【斜率优化】HDU 2993 MAX Average Problem

通道 题意:求出长度大于k子序列使得其各个元素之和的平均数最大,并输出最大平均值 思路:浅谈数形结合思想在信息学竞赛中的应用 代码: #include<stdio.h> #include<iostream> #include<string.h> #include<queue> #include<algorithm> using namespace std; const int MAXN=100010; int sum[MAXN]; int q[M

hdu3507之斜率优化DP入门

Print Article Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 4780    Accepted Submission(s): 1437 Problem Description Zero has an old printer that doesn't work well sometimes. As it is antiqu

HDU 3507 Print Article(斜率优化DP)

题目链接 题意 : 一篇文章有n个单词,如果每行打印k个单词,那这行的花费是,问你怎么安排能够得到最小花费,输出最小花费. 思路 : 一开始想的简单了以为是背包,后来才知道是斜率优化DP,然后看了网上的资料,看得还挺懂的,不过我觉得如果以后真遇到斜率DP,要推起来肯定不简单..... 网上资料1 网上资料2 1 #include <iostream> 2 #include <stdio.h> 3 4 using namespace std; 5 6 int q[500005],dp

APIO2010 特别行动队 &amp; 斜率优化DP入门讲解

做完此题之后 自己应该算是真正理解了斜率优化DP 根据状态转移方程f[i]=max(f[j]+ax^2+bx+c),x=sum[i]-sum[j] 可以变形为 f[i]=max((a*sum[j]^2-b*sum[j])-(2a*sum[j]*sum[i]))+(a*sum[i]^2+b*sum[i]+c) 我们可以把每个决策映射到平面上的一个点 其中x坐标为(a*sum[j]^2-b*sum[j])代表此决策的固定价值(与转移到哪无关) y坐标为-(2a*sum[j]) 代表此决策的潜在价值(

hdu 3669 Cross the Wall(斜率优化DP)

题目连接:hdu 3669 Cross the Wall 题意: 现在有一面无限大的墙,现在有n个人,每个人都能看成一个矩形,宽是w,高是h,现在这n个人要通过这面墙,现在只能让你挖k个洞,每个洞不能重叠,每个洞需要消耗你挖的w*h,现在问你最小消耗多少. 题解: 设dp[i][j]为前j个人挖i个洞的最小消耗. 首先我们先将每个人按w排序,我们可以发现,排序后的h是递减的,因为如果不是递减的,可以把那个点消掉,因为w[k]<w[j]&&h[k]<h[j]的话,那么第k个人就可

hdu3507 Print Article[斜率优化dp入门题]

Print Article Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others)Total Submission(s): 11761    Accepted Submission(s): 3586 Problem Description Zero has an old printer that doesn't work well sometimes. As it is antiqu