還是先簡單的介紹一下動態規劃的演算法思想,跟分治法的思想相似的是把乙個比較大的問題分解成若干子問題,而分治法分解出來的子問題都是相同規模有相同的解決辦法的,動態規劃可以通過空間換時間來解決這些相同的問題,比如說我們計算10的4次方的問題,可以分解為10^2*10^2,我們計算出了第乙個10的方時可以把答案記錄下來再計算到第二個10的方時,直接呼叫就好了。
因此,動態規劃演算法適合解決的問題有以下特點:
1.最優子結構性質(也就是說當問題分解的時候無論怎麼分解,由主問題的最優性總能推出子問題的最優性)
2.無後效性(強調歷史的任何狀態不會影響未來的決策)
3.子問題重疊性(子問題有重疊可以歸集解決)
動態規劃演算法的步驟有以下三個步驟:找出最優子結構性質——找到遞迴求解的方法——自頂向上計算出最優解
動態規劃解決的比較典型的問題就是矩陣的連乘和多邊形遊戲問題。
多邊形遊戲問題描述:開始時先構建乙個n個頂點的多邊形,每個頂點賦予乙個整數值,每個邊賦予乙個運算子(+或者*),所有邊依次用1到n進行編號。遊戲第一步將一條邊刪除,隨後n-1步按照如下操作:選擇一條邊和兩個頂點,計算出結果用結果作為數值生成乙個新的頂點替代這條邊和兩個頂點,直至所有頂點被刪除,求對於任意給定的多邊形,計算得到的最大的結果。
(來自cnblog)
演算法思路:多邊形頂點邊序列為op[i]和v[i]其中op為運算子,v為數值,op為運算子,假設最後一次合併運算發生在op[i+s],可以在op[i+s]處將鏈分為p(i,s)和p(i+s,j-s)。m1為子鏈p(i,s)的任意一種合併方式得到的值,而a,b為合併過程中可能得到的最小值和最大值即:a = m[i,i+s,0],b = m[i,i+s,1] 具體定義可見**注釋,可知a<=m1<=b。同理定義c和d,分情況考慮op[i,s] = '+' || '*' 時的最大值最小值,minf與maxf。最後在斷開位置上呼叫迴圈。**注釋很詳細...
**如下:
#include using namespace std;
const int max = 101;
int n,m[max][max][2];
//m[i,j,0]為(i,j)鏈合併得出的最小值
//m[i,j,1](i,j)鏈合併得出的最大值
int a[max];
char op[max];//用於存放運算子
//n為多邊形的邊數
//i,j分別代表頂點和邊
//s表示最優的斷開位置
//minf表示s處斷開的最小值
//maxf表示s處斷開的最大值
void minmax(int n, int i, int s, int j, int& minf, int& maxf) else ,m[i,j,1]=max
for(int m=2; m<5; m++) }}
int polymax(int n, int& p)
} }int temp=m[1][n][1];
p=1;
for(int i=2 ;i<=n; i++)
cout <
時間複雜度:多邊形遊戲問題的時間複雜度取決於polymax(),三層迴圈易知時間複雜度o(n^3)。
小白的萌點
函式本身也可以賦值給變數,即 變數可以指向函式。物件導向 的影子 變數可以指向函式,函式的引數能接收變數,那麼乙個函式就可以接收另乙個函式作為引數,這種函式就稱之為高階函式 綜上 編寫高階函式,就是讓函式的引數能夠接收別的函式 廖雪峰 reduce f,x1,x2,x3,x4 f f f x1,x2...
小LK玩積木
時間限制 1 sec 記憶體限制 128 mb 2級機械人 1級機械人 0級機械人 ab,其中第1個關節是a,第2個關節是b 3級機械人 2級機械人 1級機械人 aba,其中第1個關節是a,第2個關節是b,第3個關節是a 4級機械人 3級機械人 2級機械人 abaab 其中第1個關節是a,第2個關節...
小輝輝玩積木
渣渣輝有個兒子叫小輝輝,他非常喜歡數論。有一天,小輝輝在玩積木時,對渣渣輝提出了乙個問題 在2 n的乙個長方形方格中用乙個1 2的積木鋪滿方格輸入n 輸出鋪放方案的總數.例如n 3時為2 3方格,積木的鋪放方案有三種如下圖 輸入資料由多行組成,每行包含乙個整數n表示該測試例項的長方形方格的規格是2 ...