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

    题目链接

    bzoj3675: [Apio2014]序列分割

    题解

    可以发现,答案与分割的顺序无关,只与切在哪有关
    分割的每一块,都要保证与其他的乘一次球和,注意不要重复
    那么dp方程就是
    (dp[k][i]=dp[k-1][j]+(sum[i]-sum[j])*sum[j])
    对于割的次数那维滚掉
    对于第二维斜率优化

    代码

    #include<cstdio> 
    #include<cstring> 
    #include<algorithm> 
    inline int read() { 
        int x = 0,f = 1;
        char c = getchar(); 
        while(c < '0' || c > '9')c = getchar(); 
        while(c <= '9' && c >= '0')x = x * 10 + c - '0',c = getchar(); 
        return x * f; 
    } 
    int n,K; 
    const int maxn = 100007; 
    long long dp[maxn] , q[maxn] , g[maxn],sum[maxn],a[maxn]; 
    inline double X(int x) {return 1.0 * sum[x];} 
    inline double Y(int x) {return 1.0 * g[x] - sum[x] * sum[x];} 
    double slop(int i,int j) { 
        if(sum[i] == sum[j]) return 0; 
        return (Y(i) - Y(j)) / (X(i) - X(j)); 
    } 
    int main() { 
        n = read(),K = read(); 
        for(int i = 1;i <= n;++ i) a[i] = read(); 
        for(int i = 1;i <= n;++ i) sum[i] = sum[i - 1] + a[i];
        for(int l,r,k = 2;k <= K + 1;++ k) { 
            l = r = 0; 
            for(int i = k - 1;i <= n;++ i) { 
                while(l < r && slop(q[l + 1],q[l]) > -sum[i]) l ++; 
                    dp[i] = g[q[l]] + sum[q[l]] * (sum[i] - sum[q[l]]); 
                while(l < r && slop(q[r - 1],q[r]) < slop(q[r],i)) r --; 
                q[++ r] = i; 
            }   
            for(int j = k - 1;j <= n;++ j) g[j] = dp[j]; 
        } 
        printf("%lld
    ",dp[n]); 
        return 0; 
    } 
    
  • 相关阅读:
    修改代码一般在测试服务器
    人很臭尽量往香里去做...
    救赎
    写的css十个错误
    如何debug看源代码
    办公室倒水
    程序和思维
    mousewheel.js 和scroll api
    drupal.behavior 和 document.ready 没有直接的关系
    revision in drupal
  • 原文地址:https://www.cnblogs.com/sssy/p/9230968.html
Copyright © 2011-2022 走看看