dp入門 列基本的狀態和狀態方程

2021-07-16 08:24:31 字數 2780 閱讀 4873

1;了解一下dp的基本原理

我們要找到某個狀態的最優解,然後在它的幫助下,找到下乙個狀態的最優解。

入門**;

其中的入門題;

硬幣問題;如果我們有面值為1元、3元和5元的硬幣若干枚,如何用最少的硬幣湊夠n元;

我們用d(i)=j來表示湊夠i元最少需要j個硬幣。於是我們已經得到了d(0)=

0,表示湊夠0元最小需要0個硬幣。當i=

1時,只有面值為1元的硬幣可用,因此我們拿起乙個面值為1的硬幣,接下來只需要湊夠0元即可,而這個是已經知道答案的,即d(0)=

0。所以,d(1)=d(1

-1)+

1=d(0)+1=

0+1=

1。當i=

2時,仍然只有面值為1的硬幣可用,於是我拿起乙個面值為1的硬幣,接下來我只需要再湊夠2-1

=1元即可(記得要用最小的硬幣數量),而這個答案也已經知道了。所以d(2)=d(2

-1)+

1=d(1)+1=

1+1=

2。一直到這裡,你都可能會覺得,好無聊,感覺像做小學生的題目似的。因為我們一直都只能操作面值為1的硬幣!耐心點,讓我們看看i=

3時的情況。當i=

3時,我們能用的硬幣就有兩種了:1元的和3元的( 5元的仍然沒用,因為你需要湊的數目是3元!5元太多了親)。既然能用的硬幣有兩種,我就有兩種方案。如果我拿了乙個1元的硬幣,我的目標就變為了:湊夠3-1

=2元需要的最少硬幣數量。即d(3)=d(3

-1)+

1=d(2)+1=

2+1=

3。這個方案說的是,我拿3個1元的硬幣;第二種方案是我拿起乙個3元的硬幣,我的目標就變成:湊夠3-3

=0元需要的最少硬幣數量。即d(3)=d(3

-3)+

1=d(0)+1=

0+1=

1. 這個方案說的是,我拿1個3元的硬幣。好了,這兩種方案哪種更優呢?記得我們可是要用最少的硬幣數量來湊夠3元的。所以,選擇d(3)=

1,怎麼來的呢?具體是這樣得到的:d(3)=

min。

ok,碼了這麼多字講具體的東西,讓我們來點抽象的。從以上的文字中,我們要抽出動態規劃裡非常重要的兩個概念:狀態和狀態轉移方程。

上文中d(i)表示湊夠i元需要的最少硬幣數量,我們將它定義為該問題的"狀態",這個狀態是怎麼找出來的呢?我在另一篇文章 動態規劃之揹包問題(一)中寫過:根據子問題定義狀態。你找到子問題,狀態也就浮出水面了。最終我們要求解的問題,可以用這個狀態來表示:d(11),即湊夠11元最少需要多少個硬幣。那狀態轉移方程是什麼呢?既然我們用d(i)表示狀態,那麼狀態轉移方程自然包含d(i),上文中包含狀態d(i)的方程是:d(3)=

min。沒錯,它就是狀態轉移方程,描述狀態之間是如何轉移的。當然,我們要對它抽象一下,

d(i)=

min,其中i-vj

>=

0,vj表示第j個硬幣的面值;

有了狀態和狀態轉移方程,這個問題基本上也就解決了

#include

int main()

;//三種硬幣數;;;

while(scanf("%d",&n) != eof)}}

printf("%d\n",dp[n]);

}return

0 ;}

2最長上公升子串行;;;;

狀態轉移方程得到:

d(i) = max,其中j

#include

int main()

dp[0] = 0;

len = 1;

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

if(len < dp[i])

}printf("%d\n",len);

}return0;}

//////

//////

//////

//////

//////

//////

//////

//////

//////

//////

//////

////

//////

//////

//////

//////

//////

//////

//////

//////

//////

//////

//////

////

//////

//////

//////

//////

//////

//////

//////

//////

//////

//////

//////

////

//////

//////

//////

//////

//////

//////

//////

//////

//////

//////

//////

////

#include

int main()

b[1] = a[1];

t = 1;

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

else

else

left = middle+1;

}b[left] = a[i];} }

printf("%d\n",t);

}return

0 ;}

簡單dp的狀態轉移方程集合

1.對於任一種n的排列a,定義它的e值為序列中滿足a i i的數的個數。給定n和k k n 1000 問n的排列中e值為k的個數。dp i j 表示i個數的排列中e值為j的個數。假設現在已有乙個e值為j的i的排列,對於新加入的乙個數i 1,將其加入排列的方法有三 1 把它 放最後,加入後e值不變 2...

DP問題各種模型的狀態轉移方程

1 最長公共子串 注意和最長公共子串行區別 兩個字串str1和str2,長度分別為 l1,l2 dp i j 表示以兩個字串分別以第i和第j個字元結尾所能達到的公共子串行的長度,由於下面涉及到i 1和j 1,那麼這個時候我們一般從i 1和j 1開始到i len1,j len2。if str i 1 ...

DP問題各種模型的狀態轉移方程

原帖位址 1 最長公共子串 注意和最長公共子串行區別 兩個字串str1和str2,長度分別為 l1,l2 dp i j 表示以兩個字串分別以第i和第j個字元結尾所能達到的公共子串行的長度,由於下面涉及到i 1和j 1,那麼這個時候我們一般從i 1和j 1開始到i len1,j len2。if str...