zoukankan      html  css  js  c++  java
  • bzoj 1911: [Apio2010]特别行动队【斜率优化dp】

    仔细想想好像没学过斜率优化..
    很容易推出状态转移方程( f[i]=max{f[j]+a(s[i]-s[j])^2+b(s[i]-s[j])+c} )
    然后考虑j的选取,如果选j优于选k,那么:

    [f[j]+a(s[i]-s[j])^2+b(s[i]-s[j])+c>f[k]+a(s[i]-s[k])^2+b(s[i]-s[k])+c ]

    [f[j]+as[i]^2+as[j]^2-2as[i]s[j]+bs[i]-bs[j]+c>f[k]+as[i]^2+as[k]^2-2as[i]s[k]+bs[i]-bs[k]+c ]

    [f[j]-f[k]+as[j]^2-as[k]^2-bs[j]+bs[k]>2as[i]s[j]-2as[i]s[k] ]

    [f[j]-f[k]+a(s[j]^2-s[k]^2)-b(s[j]+s[k])>2as[i](s[j]-s[k]) ]

    [frac{f[j]-f[k]+a(s[j]^2-s[k]^2)-b(s[j]+s[k])}{2a(s[j]-s[k])}>s[i] ]

    注意这里的2a一定要除到左边不然会WA...(可能是精度问题)
    然后维护这样一个斜率单调的双端队列即可。

    #include<iostream>
    #include<cstdio>
    using namespace std;
    const int N=1000005;
    int n,a,b,c,d[N],q[N],l,r;
    long long f[N],s[N];
    int read()
    {
    	int r=0,f=1;
    	char p=getchar();
    	while(p>'9'||p<'0')
    	{
    		if(p=='-')
    			f=-1;
    		p=getchar();
    	}
    	while(p>='0'&&p<='9')
    	{
    		r=r*10+p-48;
    		p=getchar();
    	}
    	return r*f;
    }
    inline double wk(int x,int y)
    {
    	return (double)(f[y]-f[x]+a*(s[y]*s[y]-s[x]*s[x])+b*(s[x]-s[y]))/(double)(2*a*(s[y]-s[x]));
    }
    int main()
    {
    	n=read(),a=read(),b=read(),c=read();
    	for(int i=1;i<=n;i++)
    		d[i]=read(),s[i]=s[i-1]+d[i];
    	for(int i=1;i<=n;i++)
    	{
    		while(l<r&&wk(q[l],q[l+1])<s[i])
    			l++;
    		f[i]=f[q[l]]+a*(s[i]-s[q[l]])*(s[i]-s[q[l]])+b*(s[i]-s[q[l]])+c;
    		while(l<r&&wk(q[r-1],q[r])>wk(q[r],i))
    			r--;
    		q[++r]=i;
    	}
    	printf("%lld
    ",f[n]);
    	return 0;
    }
    
  • 相关阅读:
    JavaScript引用类型
    Java08_方法
    网络爬虫(一)
    openCV(四)——鼠标绘制
    openCV(三)——视频
    openCV(二)——基础绘制函数
    openCV(一) 读取保存图像
    JAVA07-数组
    JAVA06-while循环,do while循环
    JAVA05-switch多重选择
  • 原文地址:https://www.cnblogs.com/lokiii/p/8832463.html
Copyright © 2011-2022 走看看