Meaning of the questions:
The $ N (6 <= N <= 40) bit digital $, with $ K (1 <= K <= 6) $ th multiplication spaced, seeking the maximum product.
Program 1 (0pt):
See Split / Merge, consider the range of DP, think about, because the number range is limited, can not set the interval DP fucks.
Because multiplication is associative, considered "first touch $ I $ bit" and "$ j in place the first one after this multiplication $ a" two dimensions as the DP, the maximum recording, set $ f_ {i , j} $.
First, as strings of the given number set $ A $, whichever part of the function is $ cut (a, l, r) $, found from the beginning to take high and low is the same, for simplicity, just as high precision and at the lowest position for the first $ 1 $ bit.
When each generated initial value with a first multiplication, each time from the state $ j-1 $'s.
At the same time, it makes sense because you can only transfer from the calculated state unknowable and strange error to avoid doing high-precision multiplication time there, so consider maintaining access this value in the realization of the DP, to $ v $.
Consider the median $ p $ satisfying the search for a node
① $ p> = j-1 $, because here to place the first $ j-1 $ th multiplication, at least a first position $ j-1 $
② $ p <i $, from front to back transfer
③ $ f_ {p, j-1} must be accessed $
So we have
$$f_{i,j}=\mathop{max}\limits_{p=j-1}^{i-1}\{([v_{p,j-1}]*f_{p,j-1}*cut(a,p+1,i)\}$$
After running $ f_ {i} $, apparently $ f_ {i, k} $ is the answer candidate.
However, there is a problem, is read. In such hybrid digital and string input can easily be explosive. The first time submitted because of burst read into the square. Good embarrassed ah.
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; typedef long long LL; const int N=40; const int M=6; struct num{ int s[N+3],l; num(int x){ memset(s,0,sizeof s); if(x==0){ l=1; return ; } l=0; while(x>0){ s[++l]=x%10; x/=10; } } num(){} int operator[](int i){ return s[i]; } }; void prt(num a){ for(int i=a.l;i>=1;i--) putchar(a[i]+'0'); } num operator*(num a,num b){ num c=num(0); for(int i=1;i<=a.l;i++) for(int j=1;j<=b.l;j++) c.s[i+j-1]+=a[i]*b[j]; c.l=a.l+b.l+1; for(int i=1;i<c.l;i++){ c.s[i+1]+=c[i]/10; c.s[i]%=10; } while(c[c.l]==0) c.l--; return c; } bool operator<(num a,num b){ if(a.l!=b.l) return a.l<b.l; for(int i=a.l;i>=1;i--) if(a[i]!=b[i]) return a[i]<b[i]; return false; } num max(num a,num b){ if(a<b) return b; return a; } num cut(num a,int l,int r){ num b(0); b.l=r-l+1; for(int i=1;i<=b.l;i++) b.s[i]=a[l+i-1]; return b; } num a; int n,k; num f[N+3][M+3],ans[N+3]; bool v[N+3][M+3]; int main(){ scanf("%d%d",&n,&k);getchar(); char ch; a.l=n; for(int i=n;i>=1;i--){ ch=getchar(); a.s[i]=ch-'0'; } memset(v,0,sizeof 0); for(int i=1;i<n;i++){ f[i][1]=cut(a,1,i); v[i][1]=true; for(int j=2;j<=k;j++) for(int p=j-1;p<i;p++) if(v[p][j-1]){ v[i][j]=1; f[i][j]=max(f[i][j] ,f[p][j-1]*cut(a,p+1,i)); } if(v[i][k]) ans[i]=f[i][k]*cut(a,i+1,n); num maxa(0); for(int i=1;i<n;i++) if(v[i][k]) maxa=max(maxa,ans[i]); prt(maxa); return 0; }
Program 2 (100pt):
Thought a moment, it should be $ scanf $ and $ getchar $ mixed on the same line, I do not know where to go due to the carriage. In fact, I have not too thoroughly understand one of the mechanisms.
Enter consider the close up mode sequence.
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<algorithm> using namespace std; typedef long long LL; const int N=40; const int M=6; struct num{ int s[N+3],l; num(int x){ memset(s,0,sizeof s); if(x==0){ l=1; return ; } l=0; while(x>0){ s[++l]=x%10; x/=10; } } num(){} int operator[](int i){ return s[i]; } }; void prt(num a){ for(int i=a.l;i>=1;i--) putchar(a[i]+'0'); } num operator*(num a,num b){ num c=num(0); for(int i=1;i<=a.l;i++) for(int j=1;j<=b.l;j++) c.s[i+j-1]+=a[i]*b[j]; c.l=a.l+b.l+1; for(int i=1;i<c.l;i++){ c.s[i+1]+=c[i]/10; c.s[i]%=10; } while(c[c.l]==0) c.l--; return c; } bool operator<(num a,num b){ if(a.l!=b.l) return a.l<b.l; for(int i=a.l;i>=1;i--) if(a[i]!=b[i]) return a[i]<b[i]; return false; } num max(num a,num b){ if(a<b) return b; return a; } num cut(num a,int l,int r){ num b(0); b.l=r-l+1; for(int i=1;i<=b.l;i++) b.s[i]=a[l+i-1]; return b; } num a; int n,k; num f[N+3][M+3],ans[N+3]; bool v[N+3][M+3]; int main(){ scanf("%d%d\r",&n,&k); char ch; a.l=n; for(int i=n;i>=1;i--){ ch=getchar(); a.s[i]=ch-'0'; } memset(v,0,sizeof 0); for(int i=1;i<n;i++){ f[i][1]=cut(a,1,i); v[i][1]=true; for(int j=2;j<=k;j++) for(int p=j-1;p<i;p++) if(v[p][j-1]){ v[i][j]=1; f[i][j]=max(f[i][j] ,f[p][j-1]*cut(a,p+1,i)); } if(v[i][k]) ans[i]=f[i][k]*cut(a,i+1,n); num maxa(0); for(int i=1;i<n;i++) if(v[i][k]) maxa=max(maxa,ans[i]); prt(maxa); return 0; }
summary:
Terrible string engage in law ......