• 【bzoj3675】[Apio2014]序列分割 斜率优化dp


    原文地址:http://www.cnblogs.com/GXZlegend/p/6835179.html


    题目描述

    小H最近迷上了一个分隔序列的游戏。在这个游戏里,小H需要将一个长度为n的非负整数序列分割成k+1个非空的子序列。为了得到k+1个子序列,小H需要重复k次以下的步骤:
    1.小H首先选择一个长度超过1的序列(一开始小H只有一个长度为n的序列——也就是一开始得到的整个序列);
    2.选择一个位置,并通过这个位置将这个序列分割成连续的两个非空的新序列。
    每次进行上述步骤之后,小H将会得到一定的分数。这个分数为两个新序列中元素和的乘积。小H希望选择一种最佳的分割方式,使得k轮之后,小H的总得分最大。

    输入

    输入第一行包含两个整数n,k(k+1≤n)。

    第二行包含n个非负整数a1,a2,...,an(0≤ai≤10^4),表示一开始小H得到的序列。

    输出

    输出第一行包含一个整数,为小H可以得到的最大分数。

    样例输入

    7 3
    4 1 3 4 0 2 3

    样例输出

    108


    题解

    斜率优化dp

    首先可以证得分割的顺序对答案没有影响。

    设连续的3部分之和分别为a、b、c,则先分割ab再分割bc的分数为a*(b+c)+b*c=a*b+a*c+b*c,先分割bc再分割ab的分数为(a+b)*c+a*b=a*b+a*c+b*c,它们完全相同。

    这样我们就可以从左到右按顺序依次分割。

    设f[i][p]表示前i个数分割p次的最大分数,那么有f[i][p]=f[j][p-1]+(sum[i]-sum[j])*sum[j]

    这样时间复杂度为O(n^2*p),会TLE,需要优化。

    将dp方程变形,得sum[j]*sum[j]-f[j][p-1]=sum[i]*sum[j]-f[i][p],

    这样可以斜率优化来解决,此时y=sum[j]*sum[j]-f[j][p-1],k=sum[i],x=sum[j],均为正数(其实是故意这样移项的)。

    然后要求的是f[i][p]的最大值,即-f[i][p]的最小值,所以应该维护一个上凸包。

    另外需要开long long导致MLE,所以需要滚动数组。

    #include <cstdio>
    #define y(i , d) (sum[i] * sum[i] - f[i][d])
    typedef long long ll;
    ll sum[100010] , f[100010][2];
    int q[100010];
    int main()
    {
    	int n , k , i , j , l , r , d = 0;
    	scanf("%d%d" , &n , &k);
    	for(i = 1 ; i <= n ; i ++ ) scanf("%lld" , &sum[i]) , sum[i] += sum[i - 1];
    	for(j = 1 ; j <= k ; j ++ )
    	{
    		l = r = 0 , d ^= 1;
    		for(i = 1 ; i <= n ; i ++ )
    		{
    			while(l < r && y(q[l + 1] , d ^ 1) - y(q[l] , d ^ 1) <= sum[i] * (sum[q[l + 1]] - sum[q[l]])) l ++ ;
    			f[i][d] = f[q[l]][d ^ 1] + (sum[i] - sum[q[l]]) * sum[q[l]];
    			while(l < r && (y(i , d ^ 1) - y(q[r] , d ^ 1)) * (sum[q[r]] - sum[q[r - 1]]) <= (y(q[r] , d ^ 1) - y(q[r - 1] , d ^ 1)) * (sum[i] - sum[q[r]])) r -- ;
    			q[++r] = i;
    		}
    	}
    	printf("%lld
    " , f[n][k & 1]);
    	return 0;
    }

     

  • 相关阅读:
    POJ 1201 Intervals(差分约束 区间约束模版)
    POJ 3660 Cow Contest(求图的传递性)
    POJ 2267 From Dusk till Dawn or: Vladimir the Vampire(最短路变形)
    三角形面积
    欧几里得算法及扩展算法。
    康托展开和排列枚举方式
    并查集 HDU-4424
    poj 2513 并查集,Trie(字典树), 欧拉路径
    hdu 4486
    Pythagorean Triples CodeForces
  • 原文地址:https://www.cnblogs.com/GXZlegend/p/6835179.html
Copyright © 2020-2023  润新知