The main topic: The n number is divided into groups, and the number of each group in the original array should be continuous, each group will incur the cost of sum (i)-sum (j) +i-j-1-m,m is known constant. Minimum cost.
Topic Analysis: The definition of DP (i) represents the minimum cost of grouping the first I elements, and the state transition equation is obvious:
DP (i) =min (DP (j) +[sum (i)-sum (j) +i-j-1-m)]^2). Another f (i) =sum (i) +i, and the other G (i) =f (i) -1-m, the DP (i) can be organized into DP (i) =min (DP (j) +sum (j) ^2-2*g (i) *sum (j)) +g (i). It is clear that slope optimization is required.
The code is as follows:
# include<iostream># include<cstdio># include<cstring># include<algorithm>using namespace std;# define LL long longconst int n=50005;int n,m;int q[n]; LL A[n]; LL Dp[n]; ll Sum[n];void Read (ll &x) {char ch= "; while (ch< ' 0 ' | | Ch> ' 9 ') Ch=getchar (); x=0; while (ch>= ' 0 ' &&ch<= ' 9 ') {x=x*10+ch-' 0 '; Ch=getchar (); }}void init () {sum[0]=0; for (int i=1;i<=n;++i) {read (a[i]); SUM[I]=A[I]+SUM[I-1]; } for (int i=1;i<=n;++i) sum[i]+=i;} LL Getson (int k,int j) {return dp[j]-dp[k]+ (Sum[j]+sum[k]) * (Sum[j]-sum[k]);} LL getmother (int k,int j) {return (sum[j]-sum[k]);} Double getk (int i,int j) {return (double) Getson (I,J)/(double) getmother (I,J);} LL TODP (int j,int i) {return dp[j]+ (sum[i]-sum[j]-m-1) * (sum[i]-sum[j]-m-1);} LL solve () {int head=0,tail=-1; q[++tail]=0; dp[0]=0; for (int i=1;i<=n;++i) {while (HEAD+1<=TAIL&&GETK (q[head],q[head+1]) <=sum[i]-m-1) ++head; DP[I]=TODP (Q[head],i); while (HEAD+1<=TAIL&&GETK (Q[tail-1],q[tail]) >GETK (q[tail],i))--tail; Q[++tail]=i; } return dp[n];} int main () {while (~scanf ("%d%d", &n,&m)) {init (); printf ("%lld\n", Solve ()); } return 0;}
BZOJ-1010 Toy packing toy (slope optimization)