【leetcode】343. 整数拆分、【leetcode】70. 爬楼梯

343. 整数拆分

【leetcode】343. 整数拆分、【leetcode】70. 爬楼梯_第1张图片

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

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

class Solution {//记忆化搜索
private:
	vector 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(n+1, -1);//将数组中的数字全部赋值为-1 
        return breakInteger(n); 
    }
};
class Solution {//动态规划
public:
    int integerBreak(int n) {
    	vector 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]; 
    }
};

 

 

 

70. 爬楼梯

【leetcode】343. 整数拆分、【leetcode】70. 爬楼梯_第2张图片

/*具有重叠子问题,使用动态规划方法解决问题*/ 
class Solution {
public:
    int climbStairs(int n) {
        vector memo(n+1, -1);
        memo[1] = 1;//只有一节台阶时,存在一种方法 
        memo[2] = 2;//有两节台阶时,存在两种方法 
        for(int i = 3; i <= n; i++)//有三节以上的台阶时,方法数为最近一步采取走两节或者走一节台阶的方法数总和 
            memo[i] = memo[i-1] + memo[i-2];
        return memo[n];
    }
};

你可能感兴趣的:(Data,structure,and,algorithm)