leetcode 整數拆分(c++)
思路:先用暴力遞迴,之後用記憶化搜尋,最後動態規劃.
列舉所有可能:以計算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;
}
相關文章
- LeetCode-343. 整數拆分 - 題解分析LeetCode
- LeetCode 343. 整數拆分--動態規劃LeetCode動態規劃
- 四位整數位數拆分
- LeetCode題庫13. 羅馬數字轉整數(c++實現)LeetCodeC++
- LeetCode 13[羅馬數字轉整數]LeetCode
- LeetCode(7)--.反轉整數LeetCode
- (40/60)整數拆分、不同的二叉搜尋樹
- LeetCode 單詞拆分LeetCode
- LeetCode 力扣 羅馬數字轉整數LeetCode力扣
- C/C++ 合法整數與字元C++字元
- LeetCode反轉整數(Python)LeetCodePython
- [LeetCode] Reverse Integer 翻轉整數LeetCode
- leetcode13題——羅馬數字轉整數LeetCode
- [LeetCode] Integer to Roman 整數轉化成羅馬數字LeetCode
- [LeetCode] Roman to Integer 羅馬數字轉化成整數LeetCode
- P2404 自然數的拆分問題c++題解C++
- LeetCode7.整數反轉 JavaScriptLeetCodeJavaScript
- LeetCode7:ReverseInteger(整數反轉)LeetCode
- LeetCode-8. 字串轉整數 (atoi)LeetCode字串
- LeetCode_Python(13)_羅馬數字轉整數LeetCodePython
- python-leetcode13羅馬數字轉整數PythonLeetCode
- LeetCode-139-單詞拆分LeetCode
- JAVA——拆分位數Java
- C/C++模運算(正負整數)C++
- 【LeetCode-陣列】陣列式整數加法LeetCode陣列
- 每日一道 LeetCode (4):羅馬數字轉整數LeetCode
- 【leetcode】劍指 Offer 16. 數值的整數次方LeetCode
- C++ 大整數類(BigInteger類)實現C++
- .C++整數的N進位制字串表示C++字串
- C++ 中捕獲整數除零錯誤C++
- 運算整數C/C++位運算技巧C++
- 每日一道 LeetCode (2):整數反轉LeetCode
- LeetCode每日一題:整數反轉(No.7)LeetCode每日一題
- leetcode:確實的第一個整數(java)LeetCodeJava
- LeetCode題庫整理【Java】—— 7整數反轉LeetCodeJava
- LeetCode989——陣列形式的整數加法LeetCode陣列
- [LeetCode] String to Integer (atoi) 字串轉為整數LeetCode字串
- iOS Url引數拆分iOS