Channel
Test instructions: Give a string and a K, divide the string into the K-segment, each section of the method is Sigma "(i−p OS) ∗p OS", ask how to segment so that the sum is minimal
Ideas:
Set DP[I][J] is the minimum value for dividing the first J characters into the I segment. A[i] is the first character in the position of the original string.
Then dp[i][j] = min (dp[i][j],dp[i-1][k]+0*a[k+1]+1*a[k+2] + ... + (j-k+1) *a[j]-a[k+1]^2-a[j]^2)
= = "k*a[k+1]+ (k+1) *a[k+2] + ... + (j-1) *a[j]-k* (a[k+1] + ...)-a[j-.....-A[k+1]^2..
S1[] Records a[i] and, s2[] Records (I-1) *a[i] and, s3[] records a[i]^2 and
Then we can use the slope to optimize
Code:
#include <cstdio>#include<algorithm>#include<iostream>#include<cstring>using namespacestd;Const intMAXM =505;Const intMAXN =20005;intDP[MAXM][MAXN];intkey[ -],N,M,A[MAXN],S1[MAXN],S2[MAXN],S3[MAXN];intQ[maxn],hd,tl;CharSTR[MAXN];intGETDP (intJintKinti) { returndp[i-1][K] + s2[j]-s2[k]-k* (S1[j]-s1[k])-(s3[j]-s3[k]);}intGetY (intJintKinti) { return(dp[i-1][k]-s2[k]+k*s1[k]+s3[k])-(dp[i-1][j]-s2[j]+j*s1[j]+s3[j]);}intGetX (intJintk) { returnKJ;}intsolve () { for(intj=1; j<=n;j++) dp[1][J] = s2[j]-S3[j]; for(intI=2; i<=m;i++) {HD= TL =0; Q[tl+ +] = I1; for(intj=i;j<=n;j++){ while(hd+1<tl && GetY (q[hd],q[hd+1],i) <= S1[j]*getx (q[hd],q[hd+1])) hd++; DP[I][J]=GETDP (j,q[hd],i); while(hd+1<tl && GetY (q[tl-1],j,i) *getx (q[tl-2],q[tl-1]) <= GetY (q[tl-2],q[tl-1],i) *getx (q[tl-1],J)) tl--; Q[tl++] =J; } } returndp[m][n];}intMain () {intCAs; scanf ("%d",&CAs); for(intT =1; T <= cas; t++) {scanf ("%s%d",str,&m); for(intI=0; I<strlen (str); i++) {Key[str[i]-'a'] =i; } scanf ("%s", str); n =strlen (str); a[1] = key[str[0]-'a']; s1[1] = a[1];s2[1] =0; s3[1] = a[1]*a[1]; for(intI=1; i<n;i++) {A[i+1] = key[str[i]-'a']; S1[i+1] = S1[i] + a[i+1]; S2[i+1] = S2[i] + i*a[i+1]; S3[i+1] = S3[i] + a[i+1]*a[i+1]; } printf ("Case %d:%d\n", T,solve ()); } return 0;}
View Code
"Slope optimization" UVA 12594 naming babies