题目链接点击打开链接
题目大意是说有一个不超过二十位的数字,要将这个数字划分成n段,最后让这n段数字相乘,问怎么划分使乘积最大。
分析:
一个很经典的区间dp问题,我们可以先保存下这个数字的每段的大小,也就是a[i][j]表示的这个数字的i位到j位的大小。
然后就是一个很普通的区间dp了,dp[i][j]表示的是前i位里面插入j个乘号所得到的最大值。
我们知道最后的乘积肯定比原来的那个数字小,所以没有超过long long的范围。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
int const maxn = 21 ;
long long dp[maxn][maxn];
long long Arr[maxn][maxn];
int main()
{
int t,m ;
string n;
scanf("%d",&t);
while(t--)
{
memset(dp,0,sizeof(dp));
cin>>n>>m;
m--;///m-1个乘号
int len=n.length();
for(int i=0;i<len;i++)
{
Arr[i][i]=n[i]-'0';
for(int j=i+1;j<len;j++)
{
Arr[i][j]=Arr[i][j-1]*10+n[j]-'0';
}
}
for(int i=0;i<len;i++)
{
dp[i][0]=Arr[0][i];
}
for(int j=1;j<=m;j++) //j为*数目
{
for(int i=j;i<len;i++)//i为数字位置(肯定要从j开始,要包含*处理完)
{
for(int k=j-1;k<i;k++)//枚举区间
{
dp[i][j]=max(dp[i][j],dp[k][j-1]*Arr[k+1][i]);
}
}
}
printf("%lld\n",dp[len-1][m]);
}
return 0;
}
区间DP解决数字划分乘积最大化问题

本文探讨了一个利用区间DP技术解决特定数学问题的方法,即如何将一个不超过二十位的数字划分为n段,使得这些段的乘积达到最大。通过详细解释算法过程,包括初始化状态、转移方程和最终求解步骤,文章提供了从问题理解到解决方案的完整指导。
2万+

被折叠的 条评论
为什么被折叠?



