zoukankan      html  css  js  c++  java
  • bzoj.3675 [Apio2014]序列分割

    这题依旧是斜率优化DP。
    首先我们可以发现,它的分割顺序对答案没有影响:
    假设我们要将一块分为三部分,每部分的和分别为a,b,c
    a * (b+c)+b * c=a * b+a * c+b * c
    (a+b) * c+a * b=a * c+b * c+a * b
    所以,我们可以按顺序分了。
    DP式:

    f[i]=max{f[j]+a[j] * (a[i]-a[j])}

    这里的a[i]表示原a[]的前缀和

    斜率优化,我们可以得出:

    f[j]-a[j]2-f[k]+a[k]2/(a[k]-a[j])<a[i]

    上标:

    #include<cstdio>
    #define db double
    #define ll long long
    #define N 100010
    using namespace std;
    int n,K,g[N],l,len,x,las;
    ll f[2][N],a[N];
    
    inline int read()
    {
    	int x=0; char c=getchar();
    	while (c<'0' || c>'9') c=getchar();
    	while (c>='0' && c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
    	return x;
    }
    
    db solve(int x,int y) {return a[x]==a[y] ? -1e9:(db)(f[las][x]-a[x]*a[x]-f[las][y]+a[y]*a[y])/(a[y]-a[x]);}
    
    int main()
    {
    //	freopen("3675.in","r",stdin);
    //	freopen("3675.out","w",stdout);
    	n=read(),K=read();a[0]=0;
    	for (int i=1;i<=n;i++) a[i]=read()+a[i-1]; 
    	x=0,las=0;
    	for (int j=1;j<=K;j++)
    	{
    		l=len=0;x^=1;
    		for (int i=1;i<=n;i++)
    		{
    			while (l<len && solve(g[l+1],g[l])<a[i]) l++;
    			f[x][i]=f[las][g[l]]+a[g[l]]*(a[i]-a[g[l]]);
    			while (len>l && solve(g[len],g[len-1])>solve(i,g[len])) len--;
    			g[++len]=i;
    		}
    		las=x;
    	}
    	printf("%lld
    ",f[las][n]);
    	return 0;
    }
    
    转载需注明出处。
  • 相关阅读:
    Mybatis整理
    Spring获取json和表单
    Mqtt(paho)重连机制
    Redis无法获取资源(Could not get a resource from the pool)
    SSM+Maven+Redis框架学习
    第一章 Zookeeper理论基础
    RocketMQ和Kafka对比
    Kafka工作原理与过程
    Kafka介绍
    JVM调优
  • 原文地址:https://www.cnblogs.com/jz929/p/11817592.html
Copyright © 2011-2022 走看看