链接:https://www.luogu.org/problemnew/show/P1018
思路:类似区间合并,定义dp[i][j][k],表示[i,j]区间有k个乘法的最优情况
转移方程:dp[i][j][k]=max(dp[i][j][k],dp[i][s][x]*dp[s+1][j][t-x-1]),x和t见代码注释
[i,s]和[s+1,j]要合并为[i,j],[i,j]的乘号有x个,那么其子区间[i,s]和[s+1,j]的乘号和为x-1个
数据范围超long long 要使用高精度。
c/c++参考代码:(没有用高精度,不能过,要过的话,套个高精度即可)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=1e9+7;
const int maxn=45;
char s[maxn];
ll dp[maxn][maxn][10];
ll num[maxn][maxn];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
scanf("%s",s+1);
for(int i=1;i<=n;i++)
{
ll tmp=0;
for(int j=i;j<=n;j++)
{
tmp=tmp*10+s[j]-'0';
dp[i][j][0]=tmp;//预处理区间中没有乘号的状态
}
}
for(int len=1;len<n;len++)//枚举区间长度
{
for(int i=1,j=i+len;j<=n;i++,j++)//枚举起点,终点计算可得
{
for(int k=1;k<=m;k++)//枚举这个区间的乘号数
{
if(len+1<k)dp[i][j][k]=0;//不可能放下的话,直接继续循环
else
{
for(int s=i;s<j;s++)//枚举中间端点
{
dp[i][j][k]=max(dp[i][j][k],dp[i][s][0]*dp[s+1][j][k-1]);
}
}
}
}
}
printf("%lld\n",dp[1][n][m]);
return 0;
}
java代码:
import java.math.BigInteger;
import java.util.Scanner;
public class Main {
public static BigInteger Max(BigInteger a, BigInteger b){
if(a.compareTo(b) >= 0)return a;
else return b;
}
public static void main(String[] args){
Scanner cin = new Scanner(System.in);
int n,m;
n = cin.nextInt();
m = cin.nextInt();
BigInteger [][][] dp = new BigInteger[45][45][10];
BigInteger zero = new BigInteger("0");
BigInteger ten = new BigInteger("10");
cin.nextLine();
char [] ss = cin.nextLine().toCharArray();
for (int i = 1; i <= n; i++){
for (int j = 1; j <= n; j++){
for (int k = 1;k <= 6; k++){
dp[i][j][k] = zero;
}
}
}
for (int i = 0; i < n; i++){
BigInteger tmp = zero;
for (int j = i ; j < n; j++ ){
tmp = tmp.multiply(ten);
tmp = tmp.add(new BigInteger("" + (ss[j] - '0')));
dp[i + 1][j + 1][0] = tmp;
}
}
for (int len = 1; len < n; len++){
for (int i = 1, j = i + len; j <= n; j++, i++){
for (int k = 1; k <= m; k++){
if(len + 1 < k)dp[i][j][k] = zero;
else {
for (int s = i; s < j; s++){
dp[i][j][k]=Max(dp[i][j][k],dp[i][s][0].multiply(dp[s + 1][j][k - 1]));
}
}
}
}
}
System.out.println(dp[1][n][m]);
}
}