- 1、本文档共38页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
动态规划总结经典题目(经典中的经典)
动态规划总结——经典问题总结
本文着重讨论状态是如何表示,以及方程是怎样表示的。当然,还附上关键的,有可能作为模板的代码段。但有的代码的实现是优化版的。
经典问题总结
最长上升子序列(LIS)
问题描述如下:
设L=a1,a2,…,an是n个不同的实数的序列,L的递增子序列是这样一个子序列Lin=aK1,ak2,…,akm,其中k1k2…km且aK1ak2…akm。求最大的m值。
这里采用的是逆向思维的方法,从最后一个开始想起,即先从A[N](A数组是存放数据的数组,下同)开始,则只有长度为1的子序列,到A[N-1]时就有两种情况,如果a[n-1] a[n]?则存在长度为2的不下降子序列?a[n-1],a[n];如果a[n-1] a[n]?则存在长度为1的不下降子序列a[n-1]或者a[n]。
有了以上的思想,DP方程就呼之欲出了(这里是顺序推的,不是逆序的):
DP[I]=MAX(1,DP[J]+1)??J=0,1,...,I-1
但这样的想法实现起来是)O(n^2)的。本题还有更好的解法,就是O(n*logn)。利用了长升子序列的性质来优化,以下是优化版的代码:
//最长不降子序???????
const int SIZE=500001;
int data[SIZE];
int dp[SIZE];
?
//返回值是最长不降子序列的最大长度,复杂度O(N*logN)
int LCS(int n) {????????????//N是DATA数组的长度,下标从1开始
????int len(1),low,high,mid,i;
?
????dp[1]=data[1];????
????for(i=1;i=n;++i) {
???????low=1;
???????high=len;
?
???????while( low=high ) {???//二分
???????????mid=(low+high)/2;
???????????if( data[i]dp[mid] ) {
????????????????low=mid+1;
???????????}
???????????else {
????????????????high=mid-1;
???????????}
???????}
?
???????dp[low]=data[i];
???????if( lowlen ) {
????????????++len;
???????}
????}?
????return len;}
最长公共子序列(LCS)
给出两个字符串a, b,求它们的最长、连续的公共字串。
这很容易就想到以DP[I][J]表示A串匹配到I,B串匹配到J时的最大长度。则:
0??????????????????????????????I==0 || J==0
DP[I][J]=DP[I-1][J-1]+ 1??????????????????A[I]==B[J]
??????????MAX(DP[I-1][J],DP[I][J-1])???不是以上情况?
但这样实现起来的空间复杂度为O(n^2),而上面的方程只与第I-1行有关,所以可以用两个一维数组来代替。以下是代码:
??????//最长公共子序列
const int SIZE=1001;
int dp[2][SIZE];???//两个一维数组?
//输入两个字符串,返回最大的长度
int LCS(const string a,const string b) {
?????int i,j,flag;
?????memset(dp,0,sizeof(dp));
?
牋牋爁lag=1;et(
牋牋爁or(i=1;i=a.size();++i) {; s
牋牋牋牋爁or(j=1;j=b.size();++j) {strin
牋牋牋牋牋牋爄f( a[i-1]==b[j-1] )牋牋牋dp[flag][j]=dp[1-flag][j-1]+1;是优化版的代码:1]
牋牋牋牋牋牋爀lse牋牋牋牋燿p[flag][j]=MAX(dp[flag][j-1],dp[1-flag][j]);是优化版的代码:1]时就
牋牋牋牋爙牋爀lse
牋牋牋牋爁lag=1-flag;[flag
牋牋爙牋爁l
?
牋牋爎eturn dp[1-flag][b.size()];dp[
}?
01背包
???有N件物品和一个容量为V的背包。第i件物品的大小是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。
???用DP[I][J]?表示前I件物品放入一个容量为J的背包可以获得的最大价值。则
??DP[I][J]= DP[I-1][J]???????????????????????????????,JC[I]
MAX(DP[
文档评论(0)