题目大意:给定一个 N 个数组成的串,可以在串中插入 M 个乘号,求乘积最大是多少。N <= 40
阶段:前 i 个数用了 j 个乘号。
仅用阶段可以表示出一个状态,因此状态转移方程为 (dp[i][j]=max{dp[k][j-1]*val(k+1,i),kin[j,i] })。
代码如下
#include <bits/stdc++.h>
using namespace std;
const int maxn=50;
struct node{
int t[110],len;
node(){this->clear();}//构造函数需要初始化
void get_num(int a[maxn],int l,int r){
this->clear();
for(int i=r;i>=l;i--)this->t[++this->len]=a[i];
}
void operator=(const node& y){
this->clear();
for(int i=1;i<=y.len;i++)this->t[i]=y.t[i];
this->len=y.len;
}
bool operator<(const node& y){
if(this->len^y.len)return this->len<y.len;
for(int i=this->len;i>=1;i--)if(this->t[i]^y.t[i])return this->t[i]<y.t[i];
return 0;
}
node operator*(const node& y){
node x;
for(int i=1;i<=this->len;i++)
for(int j=1;j<=y.len;j++)
x.t[i+j-1]+=this->t[i]*y.t[j];//注意 i+j-1
for(int i=1;i<=105;i++)x.t[i+1]+=x.t[i]/10,x.t[i]%=10;
for(int i=105;i>=1;i--)if(x.t[i]!=0){x.len=i;break;}
return x;
}
void print(){
for(int i=this->len;i>=1;i--)printf("%d",this->t[i]);
puts("");
}
void clear(){
this->len=0;
memset(this->t,0,sizeof(this->t));
}
}dp[maxn][maxn];
int n,m,a[maxn];
char s[maxn];
void read_and_parse(){
scanf("%d%d%s",&n,&m,s+1);
for(int i=1;i<=n;i++)a[i]=s[i]-'0';
}
void solve(){
for(int i=1;i<=n;i++)dp[i][0].get_num(a,1,i);
for(int i=1;i<=n;i++)
for(int j=1;j<=min(m,i-1);j++)
for(int k=j;k<i;k++){
node t;t.get_num(a,k+1,i);
node x=t*dp[k][j-1];
if(dp[i][j]<x)dp[i][j]=x;
}
dp[n][m].print();
}
int main(){
read_and_parse();
solve();
return 0;
}