zoukankan      html  css  js  c++  java
  • BZOJ_4518_[Sdoi2016]征途_斜率优化

    BZOJ_4518_[Sdoi2016]征途_斜率优化

    Description

    Pine开始了从S地到T地的征途。
    从S地到T地的路可以划分成n段,相邻两段路的分界点设有休息站。
    Pine计划用m天到达T地。除第m天外,每一天晚上Pine都必须在休息站过夜。所以,一段路必须在同一天中走完。
    Pine希望每一天走的路长度尽可能相近,所以他希望每一天走的路的长度的方差尽可能小。
    帮助Pine求出最小方差是多少。
    设方差是v,可以证明,v×m^2是一个整数。为了避免精度误差,输出结果时输出v×m^2。

    Input

    第一行两个数 n、m。
    第二行 n 个数,表示 n 段路的长度

    Output

     一个数,最小方差乘以 m^2 后的值

    Sample Input

    5 2
    1 2 5 8 6

    Sample Output

    36

    HINT

    1≤n≤3000,保证从 S 到 T 的总路程不超过 30000


    $sum (x_i-ar{x})^{2}*m$

    $=(sum x_i^2-2sum x_iar{x}+frac{sum^2}{m})*m$

    $=msum x_i^2-sum^2$

    于是转化为分成m段,求每段和的平方和的最小值。

    设F[i][j]表示前i个数分成j段的最小答案 有F[i][j]=min(F[i][j],F[i-1][k]+(s[k]-s[j])*(s[k]-s[j]))

    设两个决策点k,l,l>k且l比k优。

    G[j]=2*s[j]>(f[i][k]-f[i][l]+s[k]*s[k]-s[l]*s[l])/(s[k]-s[l]);

    用单调队列维护一个上凸包。

    代码:

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    typedef double f2;
    typedef long long ll;
    #define N 3050
    int a[N],n,m,Q[N],L,R;
    ll f[N][N],s[N];
    f2 slope(int i,int k,int l) {
    	return (1.0*f[i][k]-f[i][l]+s[k]*s[k]-s[l]*s[l])/(s[k]-s[l]);
    }
    int main() {
    	scanf("%d%d",&n,&m);
    	int i,j;
    	for(i=1;i<=n;i++) {
    		scanf("%d",&a[i]);
    		s[i]=s[i-1]+a[i];
    		f[1][i]=s[i]*s[i];
    	}
    	f[0][0]=0;
    	for(i=2;i<=m;i++) {
    		L=R=0;
    		for(j=1;j<=n;j++) {
    			while(L<R-1&&slope(i-1,Q[L],Q[L+1])<2*s[j]) L++;
    			int k=Q[L];
    			f[i][j]=f[i-1][k]+(s[j]-s[k])*(s[j]-s[k]);
    			while(L<R-1&&slope(i-1,Q[R-1],j)<slope(i-1,Q[R-1],Q[R-2])) R--;
    			Q[R++]=j;
    		}
    	}
    	printf("%lld
    ",m*f[m][n]-s[n]*s[n]);
    }
    
  • 相关阅读:
    大数据学习操作笔记
    每日总结
    每日总结
    每日总结
    每日总结
    每日总结
    每日总结
    jstl标签,c:foreach无效的问题
    阅读笔记
    《高效能人士的7个习惯》
  • 原文地址:https://www.cnblogs.com/suika/p/9021575.html
Copyright © 2011-2022 走看看