• [APIO2014]序列分割


    题目


    用这题来复习下斜率优化(跟新学的差不多

     要想斜率优化你得现有dp式(不然优化个p

    这道题简单分析后可以得到一个简单的dp式

    设$Fi,j$表示前1~i分成$j$段的最大值(分析可知顺序无关

    $si$为1~i的和,则有

    $F_{i,k}​ = max left { F_{j,k−1}​+s_j​(s_i​−s_j​) ight }$ $(0 leq j<)$

    吼,现在我们有了dp式

    接下来我们得有个大小关系

    我们任取j,k满足 $0k<j<i$ 且 j 比 k 更优,那么有如下不等式:

    $g_j+s_j(s_i-s_j)ge g_k+s_k(s_i-s_k)$

    $frac{(g_j-{s_j}^2)-(g_k-{s_k}^2)}{s_k-s_j}leq s_i$

    有了这样一个式子再简单画个图推导一下可知需要维护的是个下凸包

    怎么说呢总感觉写的有点敷衍233

     1 #include<bits/stdc++.h>
     2 #define N 100005
     3 #define ll long long
     4 using namespace std;
     5 int n,k,a[N],q[N],l,r,pre[N][205];
     6 ll s[N],f[N],g[N];
     7 double slope(int j,int k){
     8     if(s[j]==s[k])return -1e10;
     9     return (double)((g[j]-s[j]*s[j])-(g[k]-s[k]*s[k]))/(s[k]-s[j]);
    10 }
    11 int main(){
    12     scanf("%d%d",&n,&k);
    13     for(int i=1;i<=n;i++)scanf("%d",&a[i]),s[i]=s[i-1]+a[i];
    14     for(int t=1;t<=k;t++){
    15         int l=1,r=0;
    16         q[++r]=0;
    17         for(int i=1;i<=n;i++){
    18             while(l<r&&slope(q[l],q[l+1])<=s[i])l++;
    19             f[i]=g[q[l]]+(s[i]-s[q[l]])*s[q[l]];
    20             pre[i][t]=q[l];
    21             while(l<r&&slope(q[r],i)<=slope(q[r-1],q[r]))r--;
    22             q[++r]=i;
    23         }
    24         memcpy(g,f,sizeof(f));
    25     }
    26     printf("%lld
    ",f[n]);
    27     int x=pre[n][k];
    28     printf("%d",x);
    29     for(int i=k-1;i>=1;i--){
    30         x=pre[x][i];
    31         printf(" %d",x);
    32     }
    33     return 0;
    34 }
    View Code
  • 相关阅读:
    2019-05-29 EL表达式中使用三目运算符
    2019-05-24 创建redis集群
    2019-05-24 Linux命令ps aux|grep XXX
    2019-05-24 编写批处理脚本;给权限;
    2019-05-24 网站"XXX"求把名为"cookie"的文件存放在你的计算机上,此文件可以
    挣值、预测技术
    挣值、预测
    进度网络计算
    NPV净现值
    Arguments
  • 原文地址:https://www.cnblogs.com/2017SSY/p/11012146.html
Copyright © 2020-2023  润新知