Sequence into "APIO 2014"

The meaning of problems

Given a sequence, for \ (K \) operations, each operation will be split sequence.

For each operation, to select any one section divided at any point, and obtained by multiplying the left and right gains.

Seeking maximum returns.


Thinking

Substate \ (f [i] [k ] \) representing the forward \ (I \) number of cut \ (K \) times the maximum benefit.

Release equation \ (f [i] [k ] = max (f [j] [k-1] + sum [j] * (sum [i] -sum [j])) \)

Scroll what can be removed one-dimensional.

Suppose decision point \ (x, y \) and \ (X \) than \ (Y \) , it can be simplified to give \ (\ frac {f [x ] -sum [x] ^ 2-f [y ] + SUM [Y] ^ {2} SUM [Y] -sum [X]}> [I SUM] \) . The slope optimization sets click.

// Note that this question will be \ (sum [x] == sum [y] \) case

\(end\)

Code

#include <bits/stdc++.h>

using namespace std;

namespace StandardIO {

    template<typename T>inline void read (T &x) {
        x=0;T f=1;char c=getchar();
        for (; c<'0'||c>'9'; c=getchar()) if (c=='-') f=-1;
        for (; c>='0'&&c<='9'; c=getchar()) x=x*10+c-'0';
        x*=f;
    }

    template<typename T>inline void write (T x) {
        if (x<0) putchar('-'),x*=-1;
        if (x>=10) write(x/10);
        putchar(x%10+'0');
    }

}

using namespace StandardIO;

namespace Project {
    #define int long long
    
    const int N=100010;
    
    int n,k;
    int head,tail;
    int sum[N],dp[N],dp2[N],queue[N];//,pre[N][205];
    
    inline double slope (int x,int y) {
        if (sum[x]==sum[y]) return -1e18;
        return (double)(dp2[x]-sum[x]*sum[x]-dp2[y]+sum[y]*sum[y])/(double)(sum[y]-sum[x]);
    }

    inline void MAIN () {
        read(n),read(k);
        for (register int i=1; i<=n; ++i) {
            read(sum[i]),sum[i]+=sum[i-1];
        }
        for (register int t=1; t<=k; ++t) {
            head=tail=1,queue[head]=0;
            for (register int i=1; i<=n; ++i) {
                while (head<tail&&slope(queue[head],queue[head+1])<=sum[i]) ++head;
                dp[i]=dp2[queue[head]]+sum[queue[head]]*(sum[i]-sum[queue[head]]);
//              pre[i][t]=queue[head];
                while (head<tail&&slope(queue[tail-1],queue[tail])>=slope(queue[tail],i)) --tail;
                queue[++tail]=i;    
            }
            memcpy(dp2,dp,sizeof(dp));  
        }
        write(dp[n]),putchar('\n');
//      for (register int x=n,i=k; i>=1; --i) x=pre[x][i],write(x),putchar(' ');
    }
    
    #undef int
}

int main () {
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    Project::MAIN();
}

Guess you like

Origin www.cnblogs.com/ilverene/p/11360980.html