版权声明:本博客为博主原创文章,未经博主允许,禁止转载,谢谢合作。 https://blog.csdn.net/weixin_43971252/article/details/88358632
思路:先用暴力递归,之后用记忆化搜索,最后动态规划.
枚举所有可能:以计算4为例
如上图所示,2被重复计算,所以可以使用记忆化搜索,将第一次计算得到的结果保存下来,当以后再出现时直接使用第一次计算得到的值。
vs2019运行代码
#include<iostream>
#include<algorithm> //max
#include<ctime>
#include<vector>
#include<cassert>
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<int>(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;
}