【leetcode】343. 整数拆分

343. 整数拆分

动态规划:将原问题拆解成若干子问题,同时保存子问题的答案,使得每个子问题只求解一次,最终获得原问题的答案
大部分动态规划问题本质上都是递归问题,只是在递归的过程中,会发现所谓的“重叠子问题”和“最优子结构”(通过求子问题的最优解,可以获得原问题的最优解)
对于同时拥有重叠子问题和最优子结构的问题,考虑两种解决方式:1、记忆化搜索(自顶向下解决问题,较容易实现) 2、动态规划(自底向上解决问题,代码更加简洁)

解题思路:研究递归结构->使用记忆化搜索->使用动态规划

class Solution {//记忆化搜索
private:
	vector<int> memo;
	//将n进行分割(至少分割两部分),可以获得的最大乘积 
	int breakInteger(int n){
		if(n == 1)
		    return 1;
		if(memo[n] != -1)
		    return memo[n];
		int res = -1;//res存储最大乘积 
		for(int i = 1; i <= n; i++)
			//i + (n-i)
			res = max(res, max(i*breakInter(n-i), i*(n-i)));//注意要分为两种情况,一种是只分成两个部分i和n-i,另一种i和递归breakInteger(n-i) 
		memo[n] = res;
		return res;
	}
public:
    int integerBreak(int n) {
        memo = vector<int>(n+1, -1);//将数组中的数字全部赋值为-1 
        return breakInteger(n); 
    }
};
class Solution {//动态规划
public:
    int integerBreak(int n) {
    	vector<int> memo(n+1, -1);//将数组中的数字全部赋值为-1 
    	
    	memo[1] = 1;//自底向上解决问题 

    	for(int i = 2; i <= n; i++)
    	    //求解memo[i]
			for(int j = 1; j <= i-1; j++)//j的值最小为1,最大为i-1
			    //j + (i-j)
				memo[i] = max(memo[i], max(j*(i-j), j*memo[i-j]));//由于i-j < i,所以memo[i-j]一定已经存在
			return memo[n]; 
    }
};

猜你喜欢

转载自blog.csdn.net/qq_28038873/article/details/81670661