[二分 分数规划 单调队列 最优平均值] P1419 寻找段落
Posted 鱼竿钓鱼干
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[二分 分数规划 单调队列 最优平均值] P1419 寻找段落相关的知识,希望对你有一定的参考价值。
[二分 分数规划 单调队列 最优平均值] P1419 寻找段落
题目
思路
最优平均值
经典的分数规划问题,一般用二分法来做。
对于这个问题,
b
i
=
1
b_i=1
bi=1 ,那么就是判断
∑
(
a
i
−
m
i
d
)
>
=
0
\\sum (ai-mid)>=0
∑(ai−mid)>=0这个可以用前缀和优化。然后问题转化为,求长度为S~T的最大连续子段和
这个可以用单调队列来实现
求长度为S~T的最大连续子段和的数学表示
s
u
m
[
i
]
−
m
i
n
(
s
u
m
[
i
−
s
]
,
s
u
m
[
i
−
s
+
1
]
…
…
s
u
m
[
i
−
t
]
)
sum[i]-min(sum[i-s],sum[i-s+1]……sum[i-t])
sum[i]−min(sum[i−s],sum[i−s+1]……sum[i−t])
这不就滑动窗口吗
int l=1,r=0;
for(int i=s;i<=n;i++){
while(l<=r&&sum[q[r]]>=sum[i-s])r--;//发现降序,弹出队尾
q[++r]=i-s;
while(l<=r&&q[l]<i-t)l++;//超出长度了弹出队首
if(l<=r&&sum[i]-sum[q[l]]>=0)return 1;
}
代码
// Problem: P1419 寻找段落
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P1419
// Memory Limit: 125 MB
// Time Limit: 1000 ms
// FishingRod
#include<bits/stdc++.h>
using namespace std;
#define endl "\\n"
typedef long long LL;
typedef pair<int,int> PII;
//#define MULINPUT
/*DATA & KEY
*/
int T;
const int N=1E5+10;
const double eps=1e-6;
double a[N],b[N],sum[N];
int q[N];
int n,s,t;
bool check(double mid){
double ret=0;
int l=1,r=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];
for(int i=s;i<=n;i++){
while(l<=r&&sum[q[r]]>=sum[i-s])r--;
q[++r]=i-s;
while(l<=r&&q[l]<i-t)l++;
if(l<=r&&sum[i]-sum[q[l]]>=0)return 1;
}
return 0;
}
void solve(int C)
{
//NEW DATA CLEAN
//NOTE!!!
cin>>n>>s>>t;
for(int i=1;i<=n;i++)cin>>a[i];
double l=-1e5,r=1e5;
while(fabs(r-l)>eps){
double mid=(l+r)/2;
if(check(mid))l=mid;
else r=mid;
}
printf("%.3lf",l);
}
int main()
{
#ifdef MULINPUT
scanf("%d",&T);
for(int i=1;i<=T;i++)solve(i);
#else
solve(1);
#endif
return 0;
}
以上是关于[二分 分数规划 单调队列 最优平均值] P1419 寻找段落的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ 1758WC 2010重建计划 分数规划+点分治+单调队列
bzoj3316 JC loves Mkk 二分答案 单调队列
[转]01分数规划算法 ACM 二分 Dinkelbach 最优比率生成树 最优比率环