leetcode 整数拆分(c++)

思路:先用暴力递归,之后用记忆化搜索,最后动态规划.
枚举所有可能:以计算4为例
leetcode 整数拆分(c++)_第1张图片
如上图所示,2被重复计算,所以可以使用记忆化搜索,将第一次计算得到的结果保存下来,当以后再出现时直接使用第一次计算得到的值。
vs2019运行代码

#include
#include    //max
#include
#include
#include
using namespace std;

//思路:将n的所有拆分可能全部列举出来,对这些可能进行比较得到最大值
vector<int> mem;
class Solution {

private:
	int max_three(int a, int b, int c) {
		return max(a, max(b, c));         //max只能求2项的最大值
	}

	//n拆分为至少2项
	/*
	//暴力递归
	int _IntegerBreak(int n) {

		int res = -1;
		if (n == 1)
			return 1;

		//利用题目的加法条件,将n拆分为i + (n-i)
		//利用乘法条件, i * _IntegerBreak(n - i)为i*res,每递归调用一次都会有一个最优解,连续的最优解乘积就是最后的最大值
		for (int i(1); i < n; i++)
			res = max_three(res, i*(n - i), i * _IntegerBreak(n - i));   //注意:i*(n-i)也可能是最大值,也就是只拆分为2个数 
		
		return res;
	}*/

	//记忆化搜索
	/*
	int _IntegerBreak(int n) {

		if (n == 1)
			return 1;
		if (mem[n] != -1)
			return mem[n];
		
		int res(-1);
		for (int i = 1; i <= n - 1; i++)
			res = max_three(res, i*(n - i), i * _IntegerBreak(n - i));  //将每次计算的结果都返回给res
		mem[n] = res;        //记忆,存储n的最优解
		return res;
	}*/

public:
	/*int integerBreak(int n) {
		return _IntegerBreak(n);
	}*/

	/*int integerBreak(int n) {
		assert(n >= 2);
		mem = vector(n + 1, -1);
		return _IntegerBreak(n);
	}*/

	int integerBreak(int n) {
		assert(n >= 2);
		vector<int> res(n + 1, -1);
		
		res[1] = 1;

		//先把小的数据求出来,并将结果存储在向量里,在求解大的数据时直接使用小数据的结果(求解顺序由2到n)
		//求res[n]
		for (int i = 2; i <= n; i++) {
			
			//求解res[i],把i拆为j + (i-j)
			//求解res[i]时,1<= j <=i-1 ,当j=1是为1+i-1,当j=i-1时为i-1 + (i-(i-1))
			for (int j = 1; j <= i - 1; j++)
				res[i] = max_three(res[i], j*(i - j), j*res[i - j]);
		}
			
		return res[n];
	}
};

int main()
{
	Solution s;
	int n;
	time_t start, end;
	
	while (cin >> n) {

		/*start = clock();
		cout << s.integerBreak(n) << endl;
		end = clock();
		cout << "求(" << n << ")拆分最优解暴力递归时间: " << (double)(end - start) / CLOCKS_PER_SEC << " s" << endl;
		cout << "\n";*/

		/*start = clock();
		cout << s.integerBreak(n) << endl;
		end = clock();
		cout << "求(" << n << ")拆分最优解记忆化搜索递归时间: " << (double)(end - start) / CLOCKS_PER_SEC << " s" << endl;*/

		start = clock();
		cout << s.integerBreak(n) << endl;
		end = clock();
		cout << "求(" << n << ")拆分最优解动态规划时间: " << (double)(end - start) / CLOCKS_PER_SEC << " s" << endl;
	}
	
	cin.get();
	return 0;
}

你可能感兴趣的:(LeetCode,C++)