zoukankan      html  css  js  c++  java
  • [APIO2014]序列分割

    link

    试题分析

    其实可以发现我们选择切的顺序可以颠换。

    所以我们可以设$dp(i,j)$表示为前$i$个共切$j$的最大得分,然后$dp(i,j)=max(dp(i-1,z)+s[z] imes (s[i]-s[z])),s[i]=sum_{i=1}^i  a_i$。

    然后发现这是个斜率优化的式子,但是斜率只有一项,且为-$dp(i,j)$,所以我们虽然是要去维护上凸壳但其实事实上维护下凸壳。然后就基本斜率优化操作了。

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    #define int long long
    using namespace std;
    inline int read(){
        int f=1,ans=0;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
        return f*ans;
    }
    const int N=100011;
    const int K=211;
    int f[K][N],n,k,s[N],last[K][N],que[N],dp[N],g[N],X[N],Y[N];
    signed main(){
    //    freopen("10.in","r",stdin);
        n=read(),k=read();
        for(int i=1;i<=n;i++) s[i]=s[i-1]+read();
        for(int p=1;p<=k;p++){
            int l,r;l=r=1;que[1]=0;
            for(int i=1;i<=n;i++) g[i]=f[p-1][i];
            Y[0]=s[0]*s[0]-g[0],X[0]=s[0];
            for(int i=1;i<=n;i++){
                while(l<r&&(Y[que[l+1]]-Y[que[l]])<=s[i]*(X[que[l+1]]-X[que[l]])) l++;
                f[p][i]=f[p-1][que[l]]+s[que[l]]*(s[i]-s[que[l]]);
                last[p][i]=que[l];
                X[i]=s[i],Y[i]=s[i]*s[i]-g[i];
                while(l<r&&(Y[que[r]]-Y[que[r-1]])*(X[i]-X[que[r]])>=(Y[i]-Y[que[r]])*(X[que[r]]-X[que[r-1]])) r--;
                que[++r]=i;
            }
        }
        int r=n;
        printf("%lld
    ",f[k][n]); 
        for(int i=k;i>=1;i--){
            printf("%d ",last[i][r]);
            r=last[i][r];
        }
    }
    View Code
  • 相关阅读:
    记一次博客被日的分析过程
    省钱版----查找 IoT 设备TTL线序__未完待续
    于bugku中游荡意外得到关于CBC翻转攻击思路
    清除浮动技巧总结
    程序猿的幸福
    Memcachedclientutils类
    leetcode 2 Add Two Numbers
    arduino小车入门教学——第三天(arduino基础)
    SAP MM模块 经常使用函数
    Java代码格式
  • 原文地址:https://www.cnblogs.com/si-rui-yang/p/10121667.html
Copyright © 2011-2022 走看看