1018 乘积最大

1018 乘积最大

区间DP,需要破环为链
这个问题需要用高精度来维护,比较麻烦,现在的高精度早就不玩了,我认为没必要再学了,(逃
区间DP的思想都很类似
设f[i][j][k]表示i,j区间有k个乘号的最优情况
1.首先需要维护边界值,也就是区间没有乘号的情况,有些题目的边界值类似前缀和
2.三层左右的循环来枚举区间长度、起点终点、题目维护的值,再这道题里,显然第三个枚举的是乘号的个数,有些题目枚举区间的和
3.套用区间划分的方程,通过一个点将区间划分,这次需要将划分的区间进行一个操作,在这道题里,区间长度乘边界值

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string>
using namespace std;
typedef long long ll;
const ll SIZE=50;
const ll inf=1e9+7;
ll n,m;
char s[SIZE];
ll f[SIZE][SIZE][10];//[i,j]区间有k个乘法的最优情况 
int main()
{
	cin>>n>>m;
	cin>>s+1;
	for(ll i=1;i<=n;i++)
	{
		ll temp=0;
		for(ll j=i;j<=n;j++)
		{
			temp=temp*10+s[j]-48;
			f[i][j][0]=temp;//区间没有乘号 
		}
	}
	for(ll len=1;len<n;len++)//枚举区间长度 
	{
		for(ll i=1,j=i+len;j<=n;i++,j++)//枚举起点终点
		{
			for(ll k=1;k<=m;k++)//枚举乘号个数 
			{
				if(len+1<k) f[i][j][k]=0;//不能放下乘号
				else
				{
					for(ll s=i;s<j;s++)
					{
						f[i][j][k]=max(f[i][j][k],f[i][s][0]*f[s+1][j][k-1]);
					}
				 } 
			}
		 } 
	}
	cout<<f[1][n][m]<<endl;
	return 0;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值