#include<iostream>
#include<string>
using namespace std;
using ll = long long;
ll dp[50][10];
string s;
/*
样例:1 2 4 2 8 2
考虑最终态:1 2 | 4 | 2 8 | 2
1 | 2 4 | 2 | 8 2
可以发现,最终的结构只可能是:左边一个最大3乘积,右边剩余的数。
此外,左边的最大3乘积的位数是不确定的,枚举即可。
最终答案就是:
左边6位数的最大4乘积 = max{左边5位数的最大3乘积* 2, 左边4位数的最大3乘积* 82, 左边3位数的最大3乘积* 282}
则建立dp[a][b],表示左边a位数的最大b乘积。
for(int i=2;i<=k;++i){//几乘积 dp[][i]
for(int j=i;j<=n;++j){//左边几位数 dp[j][i] (最大n乘积,至少要有n位数)
for(int p=1;p<=n-1;++p){//枚举max{}中的数
dp[j][i]= max(dp[j][i],dp[p][i-1]*getnum(p,j)); //其中的getnum(a,b)用于计算,第[a,b]位组成的数值
}
}
}
初始化状态呢?最大1乘积,就是自己
for(int i=1;i<=n;++i){//左边几位数
dp[i][1] = getnum(1,i); //左边i位数的最大1乘积
}
*/
ll getnum(int l, int r) {
//计算第a位到第b位的,对应的数字,1<=a<=b<=n
int len = r - l + 1;
ll sum = 0;
sum = stoll(s.substr(l-1, len)); //需要注意字符串截取的问题:l要减1;r要小于a
return sum;
}
void solve() {
int n, k;
cin >> n>>k; //k个乘号
k = k + 1; //最大(k+1)乘积
cin >> s;
for (int i = 1; i <= n; ++i) {//左边几位数
dp[i][1] = getnum(1, i); //左边i位数的最大1乘积
}
for (int i = 2; i <= k; ++i) {//几乘积 dp[][i]
for (int j = i; j <= n; ++j) {//左边几位数 dp[j][i] (最大n乘积,至少要有n位数)
for (int p = 1; p <= j-1; ++p) {//枚举max{}中的数 (‘max中的位数’不应该超过‘待计算的dp’的位数)
dp[j][i] = max(dp[j][i], dp[p][i - 1] * getnum(p+1, j)); //其中的getnum(a,b)用于计算,第[a,b]位组成的数值
}
}
}
cout << dp[n][k] << endl;
}
int main() {
solve();
return 0;
}
最大K乘积的分析
最新推荐文章于 2024-10-25 13:33:57 发布