题目是真的坑,__int128
都会被卡掉,所以我直接去网上搞了个高精度的类。
设 \(dp[i,j]\) 为将前 \(j\) 个数用 \(i\) 个乘号乘起来的最优解。
\(A[i,j]\) 为从第 \(i\) 个数开始到第 \(j\) 个数拼起来的数。
\[dp[i,j]=\max_{i-1+[i=1]≤k<j} \{dp[i-1,k]*A[k+1,j]\}\]
为了视觉效果,我就直接扔上来 \(60\) 的long long
代码好了
#include <iostream>
#include <cstdio>
const int max_n = 40 + 4;
const int max_k = 6 + 4;
int N, K;
long long Dp[max_k][max_n], A[max_n][max_n];
char Num[max_n];
int main()
{
scanf("%d %d", &N, &K);
scanf("%s", &Num[1]);
for(int i = 1; i <= N; ++i)
{
Num[i] -= ‘0‘;
Dp[0][i] = Dp[0][i - 1] * 10 + Num[i];
}
for(int i = 1; i <= N; ++i)
for(int j = i; j <= N; ++j)
A[i][j] = A[i][j - 1] * 10 + Num[j];
for(int i = 1; i <= K; ++i)
for(int j = i + 1; j <= N; ++j)
for(int k = (i == 1) ? 1 : i - 1; k < j; ++k)
Dp[i][j] = std::max(Dp[i][j], Dp[i - 1][k] * A[k + 1][j]);
printf("%lld\n", Dp[K][N]);
return 0;
}