题目链接 https://www.jisuanke.com/course/709/36575
题解: 参考 https://blog.youkuaiyun.com/ruzhuxiaogu/article/details/25695671#commentBox
使用动态规划,dp[i][j]表示前i个数中插入j个乘号的乘积最大值,
要求插入j个乘号,可以将j个乘号拆出最后一个单独出来,这样原来的数就分成了2部分,
假如前一部分长度为k,则dp[i][j] = max(dp[k][j-1] * number(k+1,len)), k>=j
相当于把第二部分的长度从1遍历一遍,取最大值,具体见代码或者上述参考题解
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
char ch[25] = {0};// 输入的数字字符串
int len;// 数字长度
int K;// 插入的乘号个数
ll dp[25][15];// dp[i][j] 前i个数字中插入j个乘号的最大乘积
// 计算数字l到r位的数(数字从1开始计数)
ll Product(int l,int r) {
ll res = 0;
for(int i = l;i <= r;i++) {
res = res*10 + ch[i] - '0';
}
return res;
}
int main() {
scanf("%d%d",&len,&K);
scanf("%s",ch+1);
// 动态规划
for(int i = 1;i <= len;i++) {
dp[i][0] = Product(1,i);
}
// 遍历插入的乘号数目
for(int j = 1;j <= K;j++)
// 遍历前i个数
for(int i = 1;i <= len;i++) {
if(i < j+1) continue;
ll temp = 0;
for(int k = j;k < i;k++) {
temp = max(temp,dp[k][j-1]*Product(k+1,i));
}
dp[i][j] = temp;
}
printf("%lld\n",dp[len][K]);
return 0;
}