The following:
Regardless of the large data range, first we can think of its DP solution, Dp[i][k] indicates that the first I number is divided into the maximum score of the K segment, then the transfer equation is:
Dp[i][k]=max (dp[j][k-1]+sum[j]* (sum[i]-sum[j));
However, this is obviously the kxn^2 algorithm, for 100000 of the data even if K only 200 will be timed out, so we have to reduce the one-dimensional complexity to make the algorithm into NXK complexity, The complexity of reducing the dynamic programming is usually the complexity of enumerating J by reducing the state transfer, which uses the slope optimization.
Consistent with the slope optimization practice, if there are two decision points k1,k2 and K1 < K2, set at the update I point DP value dp[i][t+1] K2 better than K1, then there are:
dp[k1][t]+sum[k1]?(sum[i]?sum[k1])<dp[k2][t]+sum[k2]?(sum[i]?sum[k2])
After this inequality is changed, it gets:
(DP [K1] [t] -sum [k1] ^2) - (DP [k2] [t] -sum [k2] ^2) _________________________________________ < sum [i] sum [K2] -sum [k1]
Remember slope[k1,k2] = The left side of the equation, then we found that there are two properties:
1. When slope[K1,k2] < sum[i] for I point K2 decision is better than K1 and always better than K1, because each number in the sequence is non-negative, for any x> i sum[x]>=sum[i] when slope[K1,K2] < s Um[i] must have slope[K1,K2] < sum[x] So every decision is monotonic, that is, when slope[K1,k2] < Sum[i], then the point after I k1 forever useless.
2. If there is k1,k2,k3 and K1 < K2 < K3, when slope[K1,k2] >slope[K2,k3], K2 This decision point will never be used, why? Because, if the update of a point I if K2 than K1, then slope[K1,K2] < Sum[i] but also because slope[K1,k2] >slope[k2,k3] so slope[K2,K3] < Sum[i] That is K3 than K2 gifted, so K2 useless, if K2 no K1 excellent, then K2 directly useless, so anyway K2 is useless.
Having these two properties, we need to maintain a queue each time only a useful decision point to reduce the time complexity of the decision that one dimension. According to the nature of 2nd, we find that the maintained queue Q must conform to such a nature, i.e. slope[Q1,Q2] < slope[q2,q3] < slope[q3,q4] < ..., otherwise the queue will have a forever useless decision point.
How do you construct this queue?
Attached code:
#include <iostream>#include <algorithm>#include <stdio.h>#define MAXN (100005)using namespace Std;intNmKQ[MAXN]; Long Long sum[maxn],dp[maxn][2],y[MAXN] [2];intMain () {scanf ("%d%d", &n,&k); for(intI=1; i<=n;i++) {scanf ("%lld", &sum[i]); sum[i]+=sum[i-1]; } for(intI=1; i<=n;i++)yI [0]=0-sum[i]*sum[i];//DPI [0]=0 for(intI=1; i<=k;i++) {intNow=i%2;intPre= (i+1)%2;intH=1, t=1;Q[h]=1; for(intj=1; j<=n;j++) { while(H<t&&sum[j]*(sum[Q[h+1]]-sum[Q[h]]) >= (y[Q[h]][pre]-y[Q[h+1]][pre]) h++; dp[j][now]=dp[Q[h]][pre]+sum[Q[h]]*(sum[j]-sum[Q[h]]);y[j] [Now]=dp[j][now]-sum[j]*sum[j]; while(h<t&& (y[Q[t-1]][pre]-y[Q[t]][pre])*(sum[j]-sum[Q[t]]) >= (y[Q[t]][pre]-y[j] [Pre])*(sum[Q[t]]-sum[Q[t-1]])) t--; t++;Q[t]=j; } }printf("%lld\ n", Dp[n][k%2]);}
Bzoj on the administrator too lazy not to record the path, Uoj on the code:
#include <iostream>#include <algorithm>#include <stdio.h>#define MAXN (100005)using namespace Std;intNmKQ[MAXN], pr[maxn][202];long Long sum[maxn],dp[maxn][2],y[MAXN] [2];intMain () {scanf ("%d%d", &n,&k); for(intI=1; i<=n;i++) {scanf ("%lld", &sum[i]); sum[i]+=sum[i-1]; } for(intI=1; i<=n;i++)yI [0]=0-sum[i]*sum[i];//DPI [0]=0 for(intI=1; i<=k;i++) {intNow=i%2;intPre= (i+1)%2;intH=1, t=1;Q[h]=0; for(intj=1; j<=n;j++) { while(H<t&&sum[j]*(sum[Q[h+1]]-sum[Q[h]]) >= (y[Q[h]][pre]-y[Q[h+1]][pre]) h++; pr[j][i]=Q[h]; dp[j][now]=dp[Q[h]][pre]+sum[Q[h]]*(sum[j]-sum[Q[h]]);y[j] [Now]=dp[j][now]-sum[j]*sum[j]; while(h<t&& (y[Q[t-1]][pre]-y[Q[t]][pre])*(sum[j]-sum[Q[t]]) >= (y[Q[t]][pre]-y[j] [Pre])*(sum[Q[t]]-sum[Q[t-1]])) t--; t++;Q[t]=j; }} cout<<dp[n][k%2]<<endl;intNow=n; while(pr[now][k]!=0) {printf("%d ", Pr[now][k]); NOW=PR[NOW][K]; k--; }printf("\ n");}
"apio2014" "bzoj3675" sequence Segmentation and code (c + +)