
算法思路:
-
依然是个区间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;
}
测试:

这篇博客探讨了一个利用动态规划(DP)解决的最大乘积划分问题。文章介绍了算法思路,通过dp[i][j]记录前i位数被划分成j段的最大乘积,并用v[i][j]表示连续数字的乘积。代码实现中,博主展示了如何计算并存储这些信息,最终找到在给定限制条件下,将数字字符串分成k段时的最大乘积。
5468





