動態規劃入門篇
本文根據B站UP主視訊總結,有需要的朋友看看到原連結看看。
參考連結: https://www.bilibili.com/video/BV12W411v7rd?from=search&seid=775970335865336023
一、求陣列中不相連的數之和最大
直接上題, 在陣列中arr[1, 2, 4, 1, 7, 8, 3] 中求不相連的數之和的最大值。
1、 實現思路
首先,求不相連的數之和, 那麼就存在一個問題, 選或者不選。如果選了ar一個數那就不能選他隔壁的數, 只能選與他相隔1的。 我們可以從最後一個數來考慮, 再遞推回去。
如下圖所示, 我們建立一個函式OPT(), 表示當前的最佳狀態(即最大值), OPT(6)即表示7個數(arr[0]~arr[6])都考慮時的最大值, 如果7個數都考慮, 那麼我們就要考慮一個問題, 第七個數 arr[6] 選不選, 所以會有兩種情況, 選arr[6] 或者不選 arr[6]。
- 選arr[6], 那麼arr[5]與arr[6]相鄰肯定不能選,所以只能考慮arr[0]~arr[4]的最佳組合, 即opt(4), 所以此時最佳狀態為 OPT(4)+arr[6].
- 不選arr[6], 那麼arr[5]就可以選擇了, 所以此時的最佳狀態應該是OPT[5]。
然後再以遞迴的思路遞推至OPT(1), OPT(0)。
2、改進
使用遞迴能夠完成題目要求, 但是使用遞迴的過程中做了很多重複的工作,這樣會使時間複雜度大大提高,我們應該避免這種情況的出現。所以我們使用一個陣列opt[i] 將每次得到的OPT(i)存放起來。
3、原始碼
#include <iostream>
#include <vector>
using namespace std;
/******************************************************************
* 函式功能: 使用遞迴,返回陣列中互不相連的數的最大和
* 傳入引數: vector陣列地址(陣列名), 陣列大小
******************************************************************/
int rec_opt(vector<int>*arr, int size)
{
int rv =0 ;
if(size == 1) //陣列中只有一個數,此時的最佳即為這個數。
{
rv = arr->at(0);
return rv;
}
else if(size == 2) //陣列中有兩個數時,判斷兩數大小,來決定最佳數。
{
if(arr->at(1)>arr->at(0))
{
rv = arr->at(1);
}
else
{
rv = arr->at(0);
}
return rv;
}
else
{
int temp_1=0, temp_2=0;
temp_1 = rec_opt(arr, size-1); //不選
temp_2 = rec_opt(arr,size-2)+arr->at(size-1); //選
if(temp_1>temp_2)
{
return temp_1;
}
else
{
return temp_2;
}
}
}
/***********************************************************************
* 函式功能: 使用動態規劃思想, 返回陣列中不相連的數之和的最大值
* 傳入引數: vector陣列地址(陣列名)
***********************************************************************/
int dp_opt(vector<int> *arr)
{
vector<int>opt;
cout<<arr->at(0)<<endl;
opt.push_back(arr->at(0));
opt.push_back(max(arr->at(0), arr->at(1)));
for(int i=2; i<arr->size(); i++)
{
int temp_1=0, temp_2=0;
temp_1 = opt.at(i-2)+arr->at(i);
temp_2 = opt.at(i-1);
opt.push_back(max(temp_1, temp_2));
}
return opt.at(arr->size()-1);
}
int main()
{
vector<int> arr;
int num=0;
cout<<"請輸入陣列大小"<<endl;
cin>>num;
for(int i=0; i<num; i++)
{
int temp=0;
cin>>temp;
arr.push_back(temp);
}
cout<<"兩數之和最大值為:"<<rec_opt(&arr, arr.size())<<endl;
cout<<"use dp..."<<endl;
cout<<"兩數之和最大值為:"<<dp_opt(&arr)<<endl;
return 0;
}
相關文章
- LeetCode入門指南 之 動態規劃思想LeetCode動態規劃
- DP 動態規劃入門 一維陣列動態規劃陣列
- 一文帶你入門動態規劃動態規劃
- 動態規劃中初識狀態壓縮(入門)動態規劃
- 動態規劃篇——線性DP動態規劃
- 動態規劃入門——動態規劃與資料結構的結合,在樹上做DP動態規劃資料結構
- 動態規劃篇——揹包問題動態規劃
- 動態規劃動態規劃
- [leetcode] 動態規劃(Ⅰ)LeetCode動態規劃
- 動態規劃法動態規劃
- 模板 - 動態規劃動態規劃
- 動態規劃初步動態規劃
- 動態規劃分析動態規劃
- 動態規劃(DP)動態規劃
- 演算法系列-動態規劃(1):初識動態規劃演算法動態規劃
- 動態規劃小結動態規劃
- [leetcode 1235] [動態規劃]LeetCode動態規劃
- 動態規劃專題動態規劃
- 動態規劃-----線性動態規劃
- 好題——動態規劃動態規劃
- 動態規劃初級動態規劃
- 淺談動態規劃動態規劃
- 3.動態規劃動態規劃
- 動態規劃題單動態規劃
- 動態規劃 總結動態規劃
- 雙序列動態規劃動態規劃
- 動態規劃方法論動態規劃
- [atcoder 358] 【動態規劃】動態規劃
- 區間動態規劃動態規劃
- 動態規劃(Dynamic programming)動態規劃
- 有關動態規劃動態規劃
- 動態規劃入門 E – 免費餡餅 (dp的另一個應用)動態規劃
- 動態規劃之數的劃分動態規劃
- 禮物的最大價值(一維動態規劃&二維動態規劃)動態規劃
- leetcode題解(動態規劃)LeetCode動態規劃
- [動態規劃] 區間 dp動態規劃
- (C++)DP動態規劃C++動態規劃
- 【CodeChef】Graph Cost(動態規劃)動態規劃