• BZOJ 3675: [Apio2014]序列分割


    3675: [Apio2014]序列分割

    Description

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

    Input

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

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

    Output

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

    Sample Input

    7 3
    4 1 3 4 0 2 3

    Sample Output

    108

    思路:

      Dp,斜率优化。

      首先考虑正常的方程F[i][j] 表示在前i个点切j次,在i点切最后一次。首先要思考好如果切割方案一样,切割顺序和答案没有关系,这样我们就可以比较容易的得出转移方程:f[i][j] = max(f[k][j-1]+(s[i]-s[j])*(s[n]-s[i])); 考虑斜率优化,这样的状态我们显然是无法斜率优化的,所以尝试把第二维拉到前面 这样

    f[i][j] 就只和f[i-1][k]有关,可以把第一维压掉,进行斜率优化,设g[j]为滚动数组,则新的转移方程为 :f[i] =max(g[j]+(s[i]-s[j])*(s[n]-s[i]));化简开得f[i] + si*si - si*sn = g[j] - sjsn +sisj; 这样把和i有关的设为Y,和j有关的设为b,把sj设为k,si即为x。Y = kx+b;

    因为s单调递增 所以各种单调递增。

    考虑对队首的维护,若Y(j,q[l]) < Y(j,q[l+1])弹出队首

    考虑对队尾的维护,当队尾第二个元素与j构成的斜率小于队尾斜率时,弹出队尾。

    其余的直接更新即可。

    把方程化成Y = KX + B的形式免去了斜率优化中的除法。常数较小

    以下是代码

    =#include <cstdio>
    #include <cstring>
    using namespace std;
    #define ll long long
    const int N = 100005;
    #define K(i) (s[i])
    #define B(i) (g[i]-s[i]*s[i])
    #define Y(i,j) (K(j)*s[i]+B(j))
    int q[N],l,r;
    ll g[N],f[N],s[N];
    bool cmp(int i,int j,int k) {
        ll x=(K(i)-K(k))*(B(j)-B(i));
        ll y=(K(i)-K(j))*(B(k)-B(i));
        return x>=y;
    }
    int main() {
        int n,k,i,x,j;
        scanf("%d%d",&n,&k);
        for(i=1;i<=n;i++) {
            scanf("%d",&x);
            s[i]=s[i-1]+x;
        }
        for(i=1;i<=k;i++) {
            l=r=0;
            for(j=i;j<=n;j++) {
                while(l<r&&Y(j,q[l])<Y(j,q[l+1]))l++;
                f[j]=Y(j,q[l]);
                while(l<r&&cmp(j,q[r-1],q[r]))r--;
                q[++r]=j;
            }
            for(j=i;j<=n;j++) {
                g[j]=f[j];
            }
        }
        printf("%lld
    ",f[n]);
    }
    

     欢迎来原博客看看>原文链接<

  • 相关阅读:
    DNN学习笔记代码学习:LogDetailInfo 荣
    DNN学习笔记代码学习:BasePortalException 荣
    DNN学习笔记代码学习:LogInfo 荣
    DNN学习笔记代码学习:ExceptionModule 荣
    DNN学习笔记代码学习:LoggingProvider 荣
    DNN学习笔记代码学习:LogProperties 荣
    DNN学习笔记代码学习:LogController 荣
    DNN学习笔记代码学习:ExceptionLogController 荣
    DNN学习笔记代码学习:LogInfoArray 荣
    DNN学习笔记代码学习:CBO 荣
  • 原文地址:https://www.cnblogs.com/Tobichi/p/9113083.html
Copyright © 2020-2023  润新知