计蒜客-乘法最大 动态规划

本文介绍了一种使用动态规划解决特定数学问题的方法,即在给定的数字串中插入指定数量的乘号,以求得最大的可能乘积。通过定义状态dp[i][j]表示前i个数中插入j个乘号的最大乘积,采用递推公式进行求解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接 https://www.jisuanke.com/course/709/36575

题解: 参考 https://blog.youkuaiyun.com/ruzhuxiaogu/article/details/25695671#commentBox

使用动态规划,dp[i][j]表示前i个数中插入j个乘号的乘积最大值,

要求插入j个乘号,可以将j个乘号拆出最后一个单独出来,这样原来的数就分成了2部分,

假如前一部分长度为k,则dp[i][j] = max(dp[k][j-1] * number(k+1,len)), k>=j

相当于把第二部分的长度从1遍历一遍,取最大值,具体见代码或者上述参考题解

#include <cstdio>
#include <algorithm> 
#include <cstring>
using namespace std;
typedef long long ll;
char ch[25] = {0};// 输入的数字字符串
int len;// 数字长度
int K;// 插入的乘号个数 
ll dp[25][15];// dp[i][j] 前i个数字中插入j个乘号的最大乘积 
// 计算数字l到r位的数(数字从1开始计数) 
ll Product(int l,int r) {
	ll res = 0;
	for(int i = l;i <= r;i++) {
		res = res*10 + ch[i] - '0';
	}
	return res;
}

int main() {
	scanf("%d%d",&len,&K);
	scanf("%s",ch+1);
	// 动态规划
	for(int i = 1;i <= len;i++) {
		dp[i][0] = Product(1,i);
	}
	// 遍历插入的乘号数目 
	for(int j = 1;j <= K;j++) 			
		// 遍历前i个数 
		for(int i = 1;i <= len;i++) {
			if(i < j+1) continue;
			ll temp = 0;
			for(int k = j;k < i;k++) {
				temp = max(temp,dp[k][j-1]*Product(k+1,i));
			}
			dp[i][j] = temp;
		}
	 
	printf("%lld\n",dp[len][K]);
	
	return 0;
}

 

网作为国内知名的编程学习平台,提供了大量与二维数组或矩阵相关的练习题,这些题目广泛涵盖了基础操作、法设以及复杂逻辑处理等方面,适合不同水平的学习者进行练习。以下是几个与二维数组或矩阵相关的典型练习题单: ### 1. 二维数组中的查找 题目要求在一个二维数组中查找特定的整数。该二维数组具有如下特性:每一行都按照从左到右递增的顺序排序,每一列也按照从上到下的顺序排序。这类题目需要利用数组的有序性来设高效的查找法。例如,可以从数组的右上角或左下角开始查找,根据当前元素与目标值的大小关系决定下一步的方向,从而在 $O(n)$ 的时间复杂度内完成查找[^4]。 ### 2. 矩阵顺时针打印 题目要求将一个矩阵按照顺时针螺旋的顺序输出。例如对于一个 $4 \times 4$ 的矩阵,输出顺序应该是从左到右第一行,接着从上到下最后一列,然后从右到左最后一行,最后从下到上第一列,依次类推直到所有元素都被访问。这类题目考察的是对数组边界的控制能力,通常采用模拟的方法,通过维护当前的边界(上、下、左、右)来逐步缩小访问范围[^1]。 ### 3. 矩阵乘法 题目要求实现两个大矩阵的乘法,并且需要考虑内存存储方式对速度的影响。在实际中,为了提高缓存命中率,通常建议将矩阵按行存储用于乘法,因为矩阵乘法的核心操作是行与列的点积,而按行存储可以保证在访问行向量时数据在内存中是连续的,从而提升性能[^2]。 ### 4. 二维数组打乱顺序 题目要求对一个二维数组进行打乱顺序的操作。这类题目通常需要利用随机数生成器,通过 Fisher-Yates 洗牌法的思想,对数组中的元素进行随机交换。需要注意的是,为了保证打乱的均匀性,每次交换的索引应该是从当前索引到数组末尾之间随机选取的[^3]。 ### 5. 矩阵置零 题目要求将一个矩阵中所有值为零的元素所在的行和列全部置零。这类问题通常需要利用额外的空间来记录需要置零的行和列,或者通过优化空间复杂度的方式(例如利用矩阵的第一行和第一列作为标记数组)来完成操作。 ### 6. 矩阵旋转 题目要求将一个矩阵顺时针旋转 90 度。这类问题可以通过分层旋转的方式解决,即逐层处理矩阵的外圈,将元素逐个移动到正确的位置。另一种方法是先对矩阵进行水平翻转,然后再进行主对角线翻转,从而达到顺时针旋转的效果。 ### 7. 矩阵中的路径 题目要求判断在一个字符矩阵中是否存在一条连续的路径,使得路径上的字符组成一个特定的字符串。这类问题通常使用深度优先搜索(DFS)或回溯法来解决,通过递归的方式尝试每一条可能的路径,并在无法继续时回溯到上一步。 ### 8. 矩阵中的最大正方形 题目要求在一个由 0 和 1 组成的矩阵中找到最大的只包含 1 的正方形。这类问题可以通过动态规划的方法解决,其中状态定义为以当前点为右下角的最大正方形的边长,状态转移方程依赖于其上方、左侧和左上方的状态值。 ### 示例代码:顺时针打印矩阵 以下是一个实现顺时针打印矩阵的示例代码: ```python def spiral_order(matrix): if not matrix: return [] result = [] top, bottom = 0, len(matrix) - 1 left, right = 0, len(matrix[0]) - 1 while top <= bottom and left <= right: # 从左到右 for i in range(left, right + 1): result.append(matrix[top][i]) top += 1 # 从上到下 for i in range(top, bottom + 1): result.append(matrix[i][right]) right -= 1 # 从右到左 if top <= bottom: for i in range(right, left - 1, -1): result.append(matrix[bottom][i]) bottom -= 1 # 从下到上 if left <= right: for i in range(bottom, top - 1, -1): result.append(matrix[i][left]) left += 1 return result ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值