zoukankan      html  css  js  c++  java
  • 【bzoj3675】 Apio2014—序列分割

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

    题意

      给出一个包含n个非负整数的序列,要求将其分割成k+1个序列,每次分割可以获得一定的分数,分数=序列分割位置左侧的数之和×序列分割位置右侧的数之和。要求最大分数是多少。

    Solution

      稍加分析,发现其实最后得到的分数与分割的先后顺序无关,这个问题卡了我好久,我还是太辣鸡了→_→。发现最后得到的分数=序列1的数字之和×序列2的数字之和×·····×序列k+1的数字之和。

      那么我们可以列出dp方程:${f[x][i]=max(f[x][i],f[x-1][j]+s[j]×(s[i]-s[j]))}$。其中${f[x][i]}$表示将区间${[1,i]}$的序列分割成当${x}$块所得到的最大分数,${s[i]}$表示${1~i}$的前缀和。可是这样的话复杂度就是${O(n*n*k)}$的了,所以我们需要斜率优化。

      最后斜率式长这样:

    $${frac{f[j]-f[k]+s[k]^2-s[j]^2}{s[k]-s[j]}<s[i]}$$

      所以当q[l]与q[l+1]满足上式时,就pop掉q[l]。

    细节

      注意f,s数组开long long,斜率的分母${s[k]-s[j]}$可能为0。

    代码

    // bzoj3675
    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    #define LL long long
    #define inf 2147483600
    #define Pi acos(-1.0)
    #define free(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
    using namespace std;
    
    const int maxn=100010;
    LL s[maxn],f[2][maxn];
    int a[maxn],q[maxn],n,m;
    
    double K(int k,int a,int b) {
    	return s[b]-s[a]==0 ? 0 : (double)(f[k][a]-f[k][b]-s[a]*s[a]+s[b]*s[b])/(double)(s[b]-s[a]);
    }
    int main() {
    	scanf("%d%d",&n,&m);
    	for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    	int x=0;
    	for (int i=1;i<=n;i++) s[i]=s[i-1]+a[i];
    	for (int k=1;k<=m;k++) {
    		x^=1;
    		int l=1,r=1;q[1]=k-1;
    		for (int i=k;i<=n;i++) {
    			while (l<r && K(x^1,q[l],q[l+1])<s[i]) l++;
    			f[x][i]=f[x^1][q[l]]+s[q[l]]*(s[i]-s[q[l]]);
    			while (l<r && K(x^1,q[r-1],q[r])>K(x^1,q[r],i)) r--;
    			q[++r]=i;
    		}
    	}
    	printf("%lld",f[x][n]);
        return 0;
    }
    

      

  • 相关阅读:
    JAVA 作业:图形界面
    操作系统实验3:内存分配与回收
    PLAN :昔日未来
    操作系统课程:调度算法
    KMP 代码 暂存
    笔试总结篇(一) : 广州X公司笔试
    雨夜静思(一)
    KMP算法详解-- 转自Matrix67
    百度笔试
    lucene中Document删除不了的问题
  • 原文地址:https://www.cnblogs.com/MashiroSky/p/5978592.html
Copyright © 2011-2022 走看看