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

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3675

    题目大意:

    将一个长度为n的非负整数序列分割成k+1个非空的子序列,每一次分割会得到一个得分,为这次所分割成的两部分中元素和的乘积,求最大的得分

    =================================================

    题解:

    斜率优化

    首先我们要发现,对于最终分割位置是一样的方案,无论过程分割的顺序是如何的,它们的得分都是每一部分中元素和的乘积,即为相等的,也就是说分割顺序不影响得分。这个很容易证的吧,懒得打了..随便化化就好了..吧~(听说是易证的我

    设f[k][i]表示第k次的分割点为i.

    那么方程就能写成f[k][i]=f[k-1][j]+(sum[i]-sum[j])*sum[j];

    我的话是将它反过来想,YY成i+1~n是已经搞好的,在1~i这里切一下j,获得的收益就是(sum[i]-sum[j])*sum[j]。

    于是,把这个化一下用斜率优化做就好啦~

    但是然而,化出来:-sum[i]*sum[j]+f[k][i]=f[k-1][j]-sum[j]^2;

    斜率

    分母是可能为0的,所以要么就移项把sum[j2]-sum[j1]乘过去,要么就像黄学长那样把可能为0的删了(不想改动的我翻到黄学长的这种做法也就这样做了233)。

    啊最后最后,如果你真的来开f[k][n]的数组是会爆空间的,要弄成滚动的..

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    typedef long long LL;
    #define maxn 101000
    
    int q[maxn],l,r,t;
    LL f[2][maxn],a[maxn],sum[maxn];
    double Y(int j){return f[1-t][j]-sum[j]*sum[j];}
    double X(int j){return sum[j];}
    double slop(int j1,int j2){return (Y(j2)-Y(j1))/(X(j2)-X(j1));}
    int read()
    {
            char c;int tmp=0;
            c=getchar();
            while (c<'0' || c>'9') c=getchar();
            while (c>='0' && c<='9')
            {
                tmp*=10;tmp+=c-'0';
                c=getchar();
            }return tmp;
    }
    int main()
    {
    	int ln,n,i,k;sum[0]=ln=0;
    	n=read();k=read();
    	for (i=1;i<=n;i++) a[i]=read();
    	for (i=1;i<=n;i++)
    	{
    		if (a[i]!=0) a[++ln]=a[i];
    		sum[ln]=sum[ln-1]+a[ln];
    	}n=ln;t=0; 
    	memset(f,0,sizeof(f));
    	for (int ii=1;ii<=k;ii++)
    	{
    		l=1;r=0;
    		for (i=ii;i<=n;i++)
    		{
    			while (l<r && slop(q[r-1],q[r])<slop(q[r],i-1)) r--;
    			q[++r]=i-1; 
    			while (l<r && slop(q[l],q[l+1])>-sum[i]) l++;
    			int j=q[l];
    			f[t][i]=f[1-t][j]+(sum[i]-sum[j])*sum[j];
    		}t=1-t;
    	}
    	printf("%lld
    ",f[1-t][n]);
    	return 0;
    }

    啊我的代码,,巨慢orzorzorz。。。读优加了也就快了几百ms,然而比起我巨慢的总时间来说简直微不足道。(每次交我都觉得我在卡评测。。。

  • 相关阅读:
    自考-信息系统开发与管理(一)首篇概述
    html乱码问题
    Failed to create client: error while trying to communicate with apiserver: 报错解决
    Helm(bitnami)部署zookeeper和kafka集群
    Helm部署RabbitMQ集群
    Kubernetes通过插件,自动发现注册Rabbitmq集群
    Kubernetes使用operator安装Redis集群
    Kubernetes部署单Redis
    Kubernetes搭建RooK+Ceph
    Kubernetes的服务质量(QoS)
  • 原文地址:https://www.cnblogs.com/Euryale-Rose/p/6527863.html
Copyright © 2011-2022 走看看