#include<stdio.h>
#include<iostream>
using namespace std;
char aa[50];
int a[50],f[50][50][10],k,n;
long long chengji(int x,int y){
long long sum=0;
for(int i=x;i<=y;i++) sum=sum*10+a[i];
return sum;
}
long long d(int i,int j,int k){
int mmax=0,t=0;
if(f[i][j][k]>0) return f[i][j][k];
else if(k==0) return chengji(i,j);//没有乘号了,返回i~j的整数(合起来)
else{
for(int l=i;l<j;l++){
for(int tk=0;tk<k;tk++){
int tki_l=tk;//左区间的乘号数
int tkl_j=k-tk-1;//右区间的乘号数
if(tki_l>(l-i)||tkl_j>(j-(l+1))) continue;//如果乘号数大于可插入乘号的位置,则跳过
else{//满足条件
t=d(i,l,tki_l)*d(l+1,j,tkl_j);
mmax=t>mmax?t:mmax;
}
}
}
return f[i][j][k]=mmax;
}
}
int main(){
freopen("1017.in","r",stdin);
freopen("1017.out","w",stdout);
cin>>n>>k;
scanf("%s",aa);
for(int i=1;i<=n;i++) a[i]=(aa[i-1]-'0');
cout<<d(1,n,k);
return 0;
}
题解:记忆化搜索,状态转移方程:d(i,j,k)=max{d(i,l,tk)*d(l+1,j,k-tk-1) | 0 < = tk < k , 0 <= l < j }. d(i,j,k)表示从i到j中插入k个乘号所得的最大值。
注意:状态转移方程要点即是状态描述完整简洁,保证不重不漏。