原题地址
https://www.luogu.org/problem/show?pid=1018
划分型DP 字符串
解题思路
1.预处理一下,把i到j截取的子串转化为数字;
2.明确dp数组表示的状态,f[i][k]表示在前i个字符划分k次得到的最大乘积;
3.初始化,f[i][0]=t[0][i](0<=i<n),即当划分次数为0时最大乘积就是前i个字符对应的数字;
4.三重循环跑DP,最外层枚举划分次数,第二层枚举i,最内一层枚举断点(断点在0到i-1范围),将大问题分解成“0~i区间内划分k次得到的最大乘积”。将j+1~i看作一个数,0~j看作已处理好的,那么就很容易得到状态转移方程:
f[i][k]=max(f[i][k],f[j][k-1]*t[j+1][i])
参考代码
#include<iostream>
#include<algorithm>
#include<cmath>
#include<string>
#include<cstdio>
using namespace std;
int f[45][10],t[45][45];
int main()
{
intn,kk;
strings;
cin>>n>>kk;
cin>>s;
intnum;
for(int i=0;i<n;i++)
{
for(int j=i;j<n;j++)
{
num=0;
for(int k=i;k<=j;k++)
num=num*10+(int)s[k]-48;
t[i][j]=num;
}
}
for(int i=0;i<n;i++)
f[i][0]=t[0][i];
for(int k=1;k<=kk;k++)
for (int i=0;i<n;i++)
for (int j=0;j<i;j++)
{
f[i][k]=max(f[i][k],f[j][k-1]*t[j+1][i]);
}
cout<<f[n-1][kk];
return0;
}