//動態規劃
//記憶化搜尋-
//遞迴自上而下的解決問題:我們沒有從乙個基本的問題開始解決,
//而是假設基本的問題已經被解決了,如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 從第一行的數開始,每次可以往下或往右下走一格,直到走到最下行,把沿途...動態規劃入門
動態規劃入門
動態規劃入門