2020_7_30

343. 整数拆分

Preface

昨天没写是因为完全搞不懂题解和答案, 也是少有的结合DFS和动归的题目,个人感觉有点写大项目的意思,所以就看看就好了。。。

今天的题目,怎么说,也是动归的基本题目吧,但是还是那个问题,怎么找到动态转移方程是一个关键。

Solution

343. 整数拆分
给定一个正整数 n,将其拆分为至少两个正整数的和,并使这些整数的乘积最大化。 返回你可以获得的最大乘积。

示例 1:

输入: 2
输出: 1
解释: 2 = 1 + 1, 1 × 1 = 1。
示例 2:

输入: 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36。
说明: 你可以假设 n 不小于 2 且不大于 58。

详细的推导过程可以去看reference部分,其实一个简单的想法,就是怎么样和前面的撤上关系,因为可能我们已经有了前面所有的除了n以外的最佳值,那么是不是就是说我们可以遍历之前的所有的值并且乘以当前遍历值与n的差值既可以找到最佳值。当然,因为我们可以最少两个正整数之和,所以在对比之前的最优解之前,也同步对比这个二分的乘积即可。

但是这样做很明显不是最优解,因为我们可能花了很多时间去探索不因该是最优解的部分,很重要的一点是,(详细去看reference的官解)在和n相差4以上其实就可以不用去探索了,因为这是浪费时间。

class Solution {
public:
	int integerBreak(int n) {
		if (n < 4)
			return n - 1;
		vector<int> dp(n + 1);
		dp[2] = 1;
		for (auto i = 3; i <=n; ++i)
		{
			dp[i] = max(max(2 * (i - 2), 2 * dp[i - 2]), max(3 * (i - 3), 3 * dp[i - 3]));
		}
		return dp[n];
	}
};

当然,正如我之前所提到的,数学可以更好的解决这种数论问题。

详细还是去看看官解好了,这里不再赘述 (因为很难我自己写出来,写出来也没人家好,2333

Reference

题目

官解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值