日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

动态规划算法学习

發(fā)布時(shí)間:2025/6/15 编程问答 14 豆豆
生活随笔 收集整理的這篇文章主要介紹了 动态规划算法学习 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

? 筆試面試中經(jīng)常會(huì)出現(xiàn)一些考察動(dòng)態(tài)規(guī)劃方面的題目,以前沒(méi)有接觸過(guò),現(xiàn)在初學(xué)做個(gè)整理。

1. 什么是動(dòng)態(tài)規(guī)劃?
???????? 和分治法一樣,動(dòng)態(tài)規(guī)劃(dynamicprogramming)是通過(guò)組合子問(wèn)題而解決整個(gè)問(wèn)題的解。
???????? 分治法是將問(wèn)題劃分成一些獨(dú)立的子問(wèn)題,遞歸地求解各子問(wèn)題,然后合并子問(wèn)題的解。
???????? 動(dòng)態(tài)規(guī)劃適用于子問(wèn)題不是獨(dú)立的情況,也就是各子問(wèn)題包含公共的子子問(wèn)題。
???????? 此時(shí),分治法會(huì)做許多不必要的工作,即重復(fù)地求解公共的子問(wèn)題。動(dòng)態(tài)規(guī)劃算法對(duì)每個(gè)子問(wèn)題只求解一次,將其結(jié)果保存起來(lái),從而避免每次遇到各個(gè)子問(wèn)題時(shí)重新計(jì)算答案。
2. 動(dòng)態(tài)規(guī)劃算法的設(shè)計(jì)
兩種方法:
???????? 自頂向下(又稱記憶化搜索、備忘錄):基本上對(duì)應(yīng)著遞歸函數(shù)實(shí)現(xiàn),從大范圍開(kāi)始計(jì)算,要注意不斷保存中間結(jié)果,避免重復(fù)計(jì)算
???????? 自底向上(遞推):從小范圍遞推計(jì)算到大范圍
動(dòng)態(tài)規(guī)劃的重點(diǎn):
???????? 遞歸方程+邊界條件
3. 爬樓梯問(wèn)題
???????? 一個(gè)人每次只能走一層樓梯或者兩層樓梯,問(wèn)走到第80層樓梯一共有多少種方法。
???????? 設(shè)DP[i]為走到第i層一共有多少種方法,那么DP[80]即為所求。很顯然DP[1]=1, DP[2]=2(走到第一層只有一種方法:就是走一層樓梯;走到第二層有兩種方法:走兩次一層樓梯或者走一次兩層樓梯)。同理,走到第i層樓梯,可以從i-1層走一層,或者從i-2走兩層。很容易得到:
???????? 遞推公式:DP[i]=DP[i-1]+DP[i-2]
???????? 邊界條件:DP[1]=1?? DP[2]=2
???????? (a)自頂向下的解法:

[cpp]?view plaincopy
  • long?long?dp[81]?=?{0};/*用于保存中間結(jié)果?
  • 否則會(huì)重復(fù)計(jì)算很多重復(fù)的子問(wèn)題*/??
  • long?long?DP(int?n)??
  • {??
  • ????if(dp[n])??
  • ????????return?dp[n];??
  • ????if(n?==?1)??
  • ????????return?1;??
  • ????if(n?==?2)??
  • ????????return?2;??
  • ????dp[n]?=?DP(n-1)?+?DP(n-2);??
  • ????return?dp[n];?????
  • }??
  • ???????? (b)自底向上的解法:

    [cpp]?view plaincopy
  • int?i;??
  • long?long?dp[81];?/*?注意當(dāng)n超過(guò)75時(shí),結(jié)果值將超過(guò)int范圍?*/??
  • dp[1]?=?1;??
  • dp[2]?=?2;??
  • for(i=3;?i?<=?80;?i++)??
  • ????dp[i]?=?dp[i-1]?+?dp[i-2];??
  • 4. 最長(zhǎng)上升子序列
    ???????? 對(duì)于序列:4 1 2 24,它的最長(zhǎng)上升子序列是1 2 4,長(zhǎng)度為3。
    ???????? 對(duì)于序列:4 2 4 25 6,它的最長(zhǎng)上升子序列是2 4 5 6,長(zhǎng)度為4
    ???????? 設(shè)a[i]表示原序列,設(shè)DP[i]表示以第i個(gè)數(shù)結(jié)尾的最長(zhǎng)上升序列的長(zhǎng)度,那么很顯然想導(dǎo)出DP[i]的值,需要在DP[k](1<=k<i)中找出滿足a[k]<a[i]最大的一項(xiàng)。假設(shè)第kk項(xiàng)是我們找到的答案,那么第i個(gè)數(shù)就可以接在第kk個(gè)數(shù)之后,成為以第i個(gè)數(shù)結(jié)尾的最長(zhǎng)升序列。如果沒(méi)有找到答案,換言之第i個(gè)數(shù)比前面的數(shù)都要小,那么DP[i]=1,也即生成了從自己開(kāi)始又以自己結(jié)尾的最長(zhǎng)升序列。綜上,我們很容易得出:
    ???????? 遞推公式:DP[i]=max(DP[k]+1,DP[i])? 1<=k<i
    ???????? 邊界條件:DP[i]=1?????????????????? 1<=i<=n
    ???????? 算法復(fù)雜度為O(n^2)

    [cpp]?view plaincopy
  • void?RiseSequence(int?Array[],?int?num)??
  • {??
  • #define?MAX_LENGTH??30??
  • ????struct??
  • ????{??
  • ????????int?SequenceValue;??/*?max?length?ending?with?this?num?*/??
  • ????????int?PreviousIndex;??/*?record?the?previous?number?*/??
  • ????}ArrayInfo[MAX_LENGTH],?temp;??
  • ????int?i;??
  • ????for(i?=?0;?i?<?num;?i++)??
  • ????{??
  • ????????int?j;??
  • ????????ArrayInfo[i].SequenceValue?=?1;??
  • ????????ArrayInfo[i].PreviousIndex?=?-1;??
  • ????????for(j?=?0;?j?<?i;?j++)??
  • ????????{??
  • ????????????if(Array[j]?<?Array[i]?&&?(ArrayInfo[j].SequenceValue?+?1?>?ArrayInfo[i].SequenceValue))??
  • ????????????{??
  • ????????????????ArrayInfo[i].SequenceValue?=?ArrayInfo[j].SequenceValue?+?1;??
  • ????????????????ArrayInfo[i].PreviousIndex?=?j;??
  • ????????????}??
  • ????????}??
  • ????}??
  • ????temp.SequenceValue?=?ArrayInfo[0].SequenceValue;??
  • ????for(i?=?1;?i?<?num;?i++)??
  • ????{??
  • ????????if(temp.SequenceValue?<?ArrayInfo[i].SequenceValue)??
  • ????????{??
  • ????????????temp.SequenceValue?=?ArrayInfo[i].SequenceValue;??
  • ????????????temp.PreviousIndex?=?i;??
  • ????????}??
  • ????}??
  • ????for(i?=?0;?i?<?temp.SequenceValue;?i++)??
  • ????{??
  • ????????printf("%d??",?Array[temp.PreviousIndex]);??/*?in?reverse?order?*/??
  • ????????temp.PreviousIndex?=?ArrayInfo[temp.PreviousIndex].PreviousIndex;??
  • ????}??
  • ????printf("\nthe?max?rising?sequence?length?is?%d\n",?temp.SequenceValue);??
  • }??
  • 5. 最長(zhǎng)公共子序列
    ???????? 給定兩個(gè)序列X和Y,稱序列Z是X和Y的公共子序列如果Z既是X的一個(gè)子序列,又是Y的一個(gè)子序列。例如,如果X={a,b,c,b,d,a,b} Y={b,d,c,a,b,a} 那么序列{b,c,a}就是X和Y的一個(gè)公共子序列,但是它并不是X和Y的最長(zhǎng)公共子序列,因?yàn)樗拈L(zhǎng)度為3。而同為X和Y公共子序列的{b,c,b,a},長(zhǎng)度為4,因?yàn)檎也坏介L(zhǎng)度為5或更大的公共子序列,所以X和Y的最長(zhǎng)公共子序列長(zhǎng)度就為4。
    ???????? 假設(shè)兩個(gè)序列數(shù)組分別為a,b。定義f(i,j)為計(jì)算到a數(shù)組第i個(gè)數(shù)、b數(shù)組第j個(gè)數(shù)時(shí)所得到的最長(zhǎng)公共子序列的長(zhǎng)度。這時(shí)有兩種情況:
    ???????? 1.假如a[i]=b[j],那么f(i,j)=f(i-1,j-1)+1
    ???????? 2.假如a[i]!=b[j],那么f(i,j)=max(f(i-1,j),f(i,j-1))
    ???????? 邊界條件為:f(i,0)=0???? 1<=i<=len(a)
    ?????????????????????????????? f(0,j)=0???? 1<=j<=len(b)
    ???????? 算法復(fù)雜度:O(n^2),len(a)表示數(shù)組a的長(zhǎng)度。

    總結(jié)

    以上是生活随笔為你收集整理的动态规划算法学习的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。