poj2018 Best Cow Fences(直接求斜率)

这道题算是给斜率优化dp打下一个基础。题目要求的平均值,用前缀和表示的话就是 ave(i,j)=SjSi1j(i1) ,如果将S函数绘在平面直角坐标系内,这就是过点Sj和点Si-1直线的斜率!于是问题转化为:平面上已知N+1 个点,Pi(i, Si),0≤i≤N,求横向距离大于等于F的任意两点连线的最大斜率。构造下凸曲线,用双端队列维护就可以了。具体证明可以参见周源2004IOI国家集训队论文。应该可以在网上搜到吧,搜不到可以去我的资源下。。。

#include<cstdio>
#include<cstring>
int const N=100000+10;
int n,f,s[N],q[N],h=0,t=1;//q中至少有两个点才做判断 
float ans,temp=0;
int main(){
//  freopen("poj2018.in","r",stdin);
    scanf("%d%d",&n,&f);
    for(int i=1;i<=n;++i){
        int x;scanf("%d",&x);s[i]=s[i-1]+x;
    }
    q[++h]=0;ans=(float)(s[f]-s[0])/f;
    for(int i=1;i+f<=n;++i){
        while(h<t&&(s[i]-s[q[t]])*(q[t]-q[t-1])<=(s[q[t]]-s[q[t-1]])*(i-q[t])) --t;
        q[++t]=i;
        while(h<t&&(s[i+f]-s[q[h]])*(i+f-q[h+1])<(s[i+f]-s[q[h+1]])*(i+f-q[h])) ++h;
        temp=(float)(s[i+f]-s[q[h]])/(i+f-q[h]);
        if(ans<temp) ans=temp;
    }
    printf("%d",(int)(1000*ans));
    return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值