動態規劃入門

2021-09-02 00:16:06 字數 2619 閱讀 2538

//動態規劃

//記憶化搜尋-

//遞迴自上而下的解決問題:我們沒有從乙個基本的問題開始解決,

//而是假設基本的問題已經被解決了,如f(n) = f(n-1) + f(n-2),

//我們假設f(n-1)和f(n-2)已經解決了,有答案了,那麼f(n)也就隨之有了答案了。

//一般能有自上而下解決問題的一定能自下而上解決。比如看下面的自上而下,再看看後面的自下而上

//大多數動態規劃問題本質其實為遞迴問題:遞迴的解決重疊子問題

//1)記憶化搜尋,從上到下;2)動態規劃,自底向上;兩者本質上是相同的。但是從上到下的方式更容易思考

//自上而下

#include #include #include #define n 40

int fibcount = 0;

long long am[n];

//自上而下

int fibsx(int n)

if(n == 1)

if(am[n] == -1)

return am[n];

}//自下而上

//沒有函式呼叫,沒有函式棧的浪費,am每一項只是訪問一次,而上面的不止一次。

int fibxs(int n)

return am[n];

}int main()

printf("\n\n\n");

time_t starttime = clock();

// time(&t1);

int res =fibsx(n);

// time(&t2);

time_t endtime = clock();

printf("fib is %d 。",res);

printf("time start,end is %f\n",difftime(endtime,starttime)/clocks_per_sec);

// printf("time t1 t2 is %f\n",difftime(t2,t1));

printf("fib count is %d\n",fibcount);

for(i=0;i<=n;i++)

return 0;

}

最近在看動態規劃的內容,看了硬幣找零問題,是乙個很好的對動態規劃演算法入門的問題。

問題描述如下:

有n種硬幣,面值分別為v1,v2,v3,…,vn,每種都有無限多個,給定非零整數s,可以選用多個硬幣,使得面值之和恰好為s。輸出所需硬幣的最小值和最大值。

動態規劃關鍵是找出狀態轉移方程, 然後依據狀態轉移方程用遞迴或遞推的方法來實現問題的求解。該問題中硬幣數目是不限的,狀態方程應重點考慮被找零的數目和硬幣面值之間的關係,問題中需要得出所需硬幣的最小值和最大值,我們用陣列d來表示當前給定的s所需的最大數目和最少數目,狀態方程即為:

d[s]=max      (1)

d[s]=min (2)

d[s]表示總數為s時所需的硬幣數,

d[ s - v[i] ]  表示用總和為s-v[i]時,所需的硬幣數,d[s-v[i]] +1表示使得面值恰好為s的硬幣數

那麼,d[s]=max表示遞推(選擇)當前方案所需的硬幣數(d[s])與方案(d[s-v[i]]+1)的較大者。

下面給出分別用遞迴和遞推的方法實現的求解:

求解最大值   

void df_max(int s, int v, int n, int d)}}

}int _tmain(int argc, _tchar* argv)

; int n = sizeof(v)/sizeof(int);

int *d = new int[s+1];

memset(d, 0, sizeof(int)*(s+1));

d[0] = 0;

df_max(s, v, n, d);

cout<<"the max result: "《遞迴法求解最小值

void df(int s, int v, int n, int d)

}}}

int _tmain(int argc, _tchar* argv)

; int n = sizeof(v)/sizeof(int);

int *d = new int[s+1];

memset(d, 1, sizeof(int)*(s+1));

d[0] = 0;

df(s, v, n, d);

cout<<"the min result: "int _tmain(int argc, _tchar* argv)

;int n = sizeof(v)/sizeof(int);

int *max = new int[s+1];

int *min = new int[s+1];

memset(max, 0, sizeof(int)*(s+1));

//注意這裡初始值的設定,s為1時需要一枚硬幣

memset(min, 1, sizeof(int)*(s+1));

min[0] = 0;

c_max_min(s, v, n, max, min);

cout<< max[s] << ' ' << min[s]

}

動態規劃入門

1 用 dp 做的題大多數返回值是int boolean,求max min,不能打亂原來輸入順序。2 動態規劃有兩個重要定義,乙個叫 optimal substructure 另乙個叫 overlap subproblem 各種排序 tree 類問題中,都會用到 divide conquer 的思想...

動態規劃入門

大家可以看看這篇文章dp,哪個更容易理解就看哪個!一 動態規劃的定義 動態規劃程式設計是一種針對於解決最優化問題的一種途徑 一種方法,而不是一種特殊演算法,也就是說它沒有固定的模板。在動態規劃中,每走一步都要看看能不能最優,而且動態規劃最擅長的就是多階段問題!二 動態規劃的基本概和基本模型構成 1....

動態規劃入門

學動態規劃自然要從數字三角形開始起步,那麼我們就先從數字三角形開始。數字三角形題目 有乙個由非負整數組成的三角形,第一行只有乙個數,除了最下行之外的每個數的左下方和右下方各有乙個數,如下圖所示 3 24 10 1 4 3 2 20 從第一行的數開始,每次可以往下或往右下走一格,直到走到最下行,把沿途...