• [APIO2014]序列分割


    洛咕

    题意:试将一个长度为(N(N<=100000))的序列分成(M+1)块,每一次选择一个有超过一个元素的块(初始时你只有一块,即整个序列)选择两个相邻元素把这个块从中间分开,得到两个非空的块.每次操作后你将获得那两个新产生的块的元素和的乘积的分数.求最大总得分,并输出任意一种方案.

    分析:首先我们猜一个结论,就是对于一个序列,我们割的顺序不影响最后的得分.

    非正规非严谨证明:假设一个序列最后被我们分成了(a,b,c)三块,那么不论是先分成(a)(b,c),还是先分成(a,b)(c),最后的得分都是(a*(b+c)+b*c=(a+b)*c+a*b=ab+ac+bc).证毕.

    既然与顺序无关,那我们就假设是从前往后分的.设(f[i][j])表示将前i个数分成j块的最大得分,最后的答案应该是(f[n][m+1]),则有

    (f[i][j]=f[k][j-1]+(sum[i]-sum[k])*(sum[n]-sum[i]))其中(k<i).

    (l<k)且k比l更优,即

    (f[k][j-1]+(sum[i]-sum[k])*(sum[n]-sum[i])>f[l][j-1]+(sum[i]-sum[l])*(sum[n]-sum[i]))

    整理一下这个式子得到,

    (frac{f[k][j-1]-f[l][j-1]}{sum[k]-sum[l]}>sum[n]-sum[i])

    就可以愉快地斜率优化了.

    一开始以为是被卡常了,最后几个大数据点一直超时,然后各种卡常,滚动数组,最后好像主要是因为中间那几个乘积爆了(int),乘上(1ll)就好了.

    题目还要求输出任意一种方案,根据套路,再开一个pre数组,每次转移时记录一下从哪里转移来的,最后从(pre[n][m+1])往前找就行了.

    #include<bits/stdc++.h>
    #define N 100005
    #define M 205
    #define LL long long
    #define rg register
    using namespace std;
    inline int read(){
       int s=0,w=1;char ch=getchar();
       while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
       while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();}
       return s*w;
    }
    int q[N],pre[N][M],sum[N];LL f[N][2];
    int main(){
        int n=read(),m=read();
        for(rg int i=1;i<=n;++i)sum[i]=read(),sum[i]+=sum[i-1];
        for(rg int j=1;j<=m+1;++j){
    		rg int l=1,r=1;q[1]=0;
    		for(rg int i=1;i<=n;++i){
    	    	while(l<r&&(f[q[l+1]][(j-1)&1]-f[q[l]][(j-1)&1])>=(1ll*(sum[n]-sum[i])*(sum[q[l+1]]-sum[q[l]])))l++;
    	    	f[i][j&1]=f[q[l]][(j-1)&1]+1ll*(sum[i]-sum[q[l]])*(sum[n]-sum[i]);
    	    	pre[i][j]=q[l];
    	    	while(l<r&&(1ll*(f[q[r]][(j-1)&1]-f[q[r-1]][(j-1)&1])*(sum[i]-sum[q[r]]))<=(1ll*(f[i][(j-1)&1]-f[q[r]][(j-1)&1])*(sum[q[r]]-sum[q[r-1]])))r--;
    	    	q[++r]=i;
    		}
        }
        printf("%lld
    ",f[n][(m+1)&1]);
        for(rg int i=m+1;i>=2;--i){
    		printf("%d ",pre[n][i]);
            n=pre[n][i];
        }
        return 0;
    }
    
    
  • 相关阅读:
    jupyter安装出现问题:安装后无法打开
    GitHub上传文件问题总结
    GitHub上传文件夹
    ELK 搭建
    mysql 开放远程连接权限连不上
    mysql linux下安装
    多个springboot项目部署到tomcat,Error deploying web application archive
    mysql 新增时,唯一索引冲突时更新
    日期计算
    mysql 忘记密码
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11010910.html
Copyright © 2020-2023  润新知