dp[i][k]表示在1..i切k刀,分成k+1部分的最大乘积。a[i][j]表示s[i…j]这个数。状态数
O(nm)
,预处理
O(n2)
,决策
O(n)
,转移
O(1)
,总的时间复杂度
O(n2m)
。按照题目叙述应该高精,太懒没写。。居然水过。。。嗯,noip嘛,骗分就好了。
upd:最新版看这里:传送门
#include <cstdio>
#include <cstring>
#include <iostream>
#define ll long long
using namespace std;
int const N=41;
int n,m;
ll s,a[N][N],dp[N][7];
int main(){
// freopen("multmax.in","r",stdin);
// freopen("multmax.out","w",stdout);
scanf("%d%d",&n,&m);scanf("%lld",&s);
for(int i=n;i>=1;--i) a[i][i]=s%10,s/=10;
for(int i=1;i<n;i++)
for(int j=i+1;j<=n;j++) a[i][j]=a[i][j-1]*10+a[j][j];
for(int i=1;i<=n;i++) dp[i][0]=a[1][i];
for(int k=1;k<=m;k++)//砍k刀
for(int i=k+1;i<=n;i++)//在前i个砍
for(int j=k;j<i;j++)
dp[i][k]=max(dp[i][k],dp[j][k-1]*a[j+1][i]);
printf("%lld",dp[n][m]);
return 0;
}