Divide DP
Turn the ring chain (read 4 3-1 2 to 4 3-1 2 4 3-1 2)
Set Dp[i][j][k] In order to divide the i~j into k parts, the numbers in each part are added together, the sum of the K results of 10 modulo and then multiply, the final result of a number, the maximum or minimum value of this number.
Dp[i][j][k]=max/min{dp[i][p][k-1]+func (P+1,J)}
i+k-2<=p<=j-1 func (i,j) = (sum (i,j)%10+10)%10
(Note that there are negative values, so write: (x%10+10)%10)
Boundary: Dp[i][j][1]=func (I,J)
Answer: Max/min (Dp[i][i+n-1][m]) I=1 to N+1
The code is as follows:
#include <iostream>#defineMax_n 55#defineMax_m 15#defineMax_int 1000000000using namespacestd;intdp1[max_n*2][max_n*2][max_m];intdp2[max_n*2][max_n*2][max_m];inta[max_n*2];ints[max_n*2];intN,m;inlineintSumintLintR) {returns[r]-s[l-1]; }inlineintFuncintLintR) {return(SUM (l,r)%Ten+Ten)%Ten; } intMain () {CIN>>n>>m; for(intI=1; i<=n;i++) {cin>>A[i]; A[i+n]=A[i]; } s[0]=0; for(intI=1; i<=n*2; i++) {S[i]=s[i-1]+A[i]; } for(intI=1; i<=n*2; i++){ for(intj=i;j<=n*2; j + +) {//Borderdp1[i][j][1]=dp2[i][j][1]=func (I,J); } } for(intI=1; i<=n*2; i++){ for(intj=i;j<=n*2; j + +){ for(intk=2; k<=m;k++) {Dp1[i][j][k]=-Max_int; DP2[I][J][K]=Max_int; for(intp=i+k-2;p <=j-1;p + +) {Dp1[i][j][k]=max (Dp1[i][j][k], dp1[i][p][k-1]*func (p+1, J)); DP2[I][J][K]=min (Dp2[i][j][k], dp2[i][p][k-1]*func (p+1, J)); } } } } intans1=-Max_int; intAns2=Max_int; for(intI=1; i<=n+1; i++) {ans1=max (ans1,dp1[i][i+n-1][m]); Ans2=min (ans2,dp2[i][i+n-1][m]); } cout<<ans2<<endl<<ans1<<Endl; return 0;}
code1085 Digital Games