算法思路:
-
依然是个区间dp问题。前面如何分段会直接影响分段乘积的最大值,所以应该记录每种分段的情况。故可以用dp[i][j] 枚举记录前i位数被划分成j段的最大乘积。
-
为了便于计算分段后的整数乘积,可以用v[i][j]表示num[i]num[i+1]…num[j]的数值大小。
代码实现:
#include<bits/stdc++.h>
using namespace std;
#define N 10010
int n,k;
char num[N];
int dp[N][N]; // dp[i][j] 表示前i位数被划分成j段的最大乘积
int v[N][N]; //v[i][j] 表示num[i]num[i+1]...num[j]的数值大小
int main(){
scanf("%d%d",&n,&k);
scanf("%s",num+1);
for(int i=1;i<=n;i++){
v[i][i]=num[i]-'0';
for(int j=i+1;j<=n;j++){
v[i][j]=v[i][j-1]*10+(num[j]-'0');
}
}
for(int i=1;i<=n;i++){
dp[i][1]=v[1][i];
for(int j=2;j<=min(k,i);j++){
for(int k=j-1;k<i;k++){
dp[i][j]=max(dp[i][j],dp[k][j-1]*v[k+1][i]);
}
}
}
printf("%d",dp[n][k]);
return 0;
}