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

    题意

    Here

    思考

    这题竟然卡常 (+) 卡精度,我 (……)

    (f[i][k]) 表示前 (i) 个元素分了 (k) 次的最大值,我们可以得出转移方程((sum[])为前缀和数组):

    [f[i][k] = max{f[j][k-1] + sum[j] * (sum[i] - sum[j])} ]

    这一个转移朴素来算是 (O(n^2k)) 的复杂度,我们不妨把式子拆开:

    [f[i][k] = f[j][k-1] + sum[j] * (sum[i] - sum[j])\ = f[j][k-1] + sum[i]*sum[j] - sum[j] ^ 2\ f[i][k] - sum[i] * sum[j] = f[j][k-1] - sum[j]^2]

    (f[i][k]) 看作 (y) 上截距, (sum[j]) 看作自变量, (f[j][k-1] - sum[j]^2) 看作因变量,(-sum[i]) 则为斜率,由于(-sum[i]) 单调递减,我们可以考虑斜率优化,维护一个上凸包,复杂度为 (O(nk)),空间的话,(f[][]) 数组可以滚动,但是我太懒了,所以没滚(……)

    由于卡常,我开了 (O2) (我太菜了)

    有一点要注意的就是计算斜率的时候分母有可能为 (0),我们特判一下

    代码

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef long double D;
    const int N = 100010;
    const int K = 220;
    ll f[N][K], a[N], sum[N], q[N], road[N][K], n, kmax;
    D X(int j){ return (D)sum[j]; }
    D Y(int j, int k){ return (D)f[j][k-1] - (D)sum[j] * (D)sum[j]; }
    D slope(int i, int j, int k){
        if(sum[i] == sum[j]) return -0x3f3f3f3f;
        return ( Y(i, k) - Y(j, k) ) / ( X(i) - X(j) );
    }
    void print(int i, int k){
        if(k == 0) return;
        print(road[i][k], k-1);
        printf("%lld ", road[i][k]);
    }
    int main(){
        scanf("%lld%lld", &n, &kmax);
        for(int i=1; i<=n; i++) scanf("%lld", &a[i]), sum[i] = sum[i-1] + a[i];
        for(int k=1; k<=kmax; k++){
            int h = 1, t = 1; q[1] = 0;
            for(int i=1; i<=n; i++){
                while(h < t && slope(q[h], q[h + 1], k) >= -sum[i] ) h ++;
                f[i][k] = f[q[h]][k-1] + sum[q[h]] * (sum[i] - sum[q[h]]);
                road[i][k] = q[h];
                while(h < t && slope(q[t - 1], q[t], k) <= slope(q[t], i, k) ) t --;
                q[++t] = i;
            }
        }
        printf("%lld
    ", f[n][kmax]);
        print(n, kmax);
        return 0;
    }
    
    

    总结

    注意精度??

    注意分母为 (0) 的特判

    注意常数优化

  • 相关阅读:
    游戏 黑白棋
    题解 P2472 【[SCOI2007]蜥蜴】
    题解 P1682 【过家家】
    题解 P3153 【[CQOI2009]跳舞】
    题解 P2763 【试题库问题】
    题解 P1345 【[USACO5.4]奶牛的电信Telecowmunication】
    网络流----最大流
    Tarjan缩点
    C#之抽象类
    C#之深复制学习案例
  • 原文地址:https://www.cnblogs.com/alecli/p/10080149.html
Copyright © 2011-2022 走看看