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...