acm动态规划总结

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

动态规划题目总结(一)

对于一个有数字组成的二叉树,求由叶子到根的一条路径,使数字和最大,如:

7

38

8 1 0

2 7 4 4

4 5 2 6 5

这个是经典的动态规划,也是最最基础、最最简单的动态规划,典型的多段图。思路就是建立一个数组,由下向上动态规划,保存页子节点到当前节点的最大值,Java核心代码如下:

for(int i=num-2;i>=0;i--){

for(int j=0;j<=i;j++){

//该句是整个动态规划的核心

number[i][j]=Math.max(number[i+1][j],number[i+1][j+1])+number[i][j];

}

}

Pku acm 1579 Function Run Fun 动态规划题目总结(二)

Consider a three-parameter recursive function w(a, b, c):

if a <= 0 or b <= 0 or c <= 0, then w(a, b, c) returns: 1

if a > 20 or b > 20 or c > 20, then w(a, b, c) returns: w(20, 20, 20)

if a < b and b < c, then w(a, b, c) returns: w(a, b, c-1) + w(a, b-1, c-1) - w(a, b-1, c)

otherwise it returns: w(a-1, b, c) + w(a-1, b-1, c) + w(a-1, b, c-1) - w(a-1, b-1, c-1)

这本身就是一个递归函数,要是按照函数本身写递归式,结果肯定是TLE,这里我开了一个三维数组,从w(0,0,0)开始递推,逐步产生到w(20,20,20)的值,复杂度O(n^3).

总结:这道题是很地道的DP,因为它的子问题实在是太多了,所以将问题的结果保存起来,刘汝佳《算法艺术和信息学竞赛》中115页讲到自底向上的递推,这个例子就非常典型。总体来说这个题目还是非常简单的,不过这个思想是地道的动态规划。

Pku acm 2081 Recaman's Sequence 动态规划题目总结(三)

一道很简单的动态规划,根据一个递推公式求一个序列,我选择顺序的求解,即自底向上的递推,一个int数组result根据前面的值依此求出序列的每一个结果,另外一个boolean数组flag[i]记录i是否已经出现在序列中,求result的时候用得着,这样就避免

了查找。核心的java代码为:

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

{

if(result[i-1]-i>0&&flag[result[i-1]-i]==false)

{

result[i] = result[i-1]-i;

flag[result[i-1]-i] = true;

}

else

{

result[i] = result[i-1]+i;

flag[result[i-1]+i] = true;

}

}

Pku acm 1953 World Cup Noise 动态规划题目总结(四)

给定一个小于45的整数n,求n位2进制数中不含相邻1的数的个数。看似简单的一

对于n=1来说,以1结尾、以0结尾个数都是1,总和是2,下面过度到2:对于所有以1结尾的数,后面都可以加上0,变为n=2时以0结尾的,而只有结尾为0的数才能加上1(因为不能有两个连续0),这样就可以在n=2的格里分别填上1、2,总和算出来为3,以此类推,我们可以算出所有n<=45的值,然后根据输入进行相应输出。核心代码如下:int i,num,count,array[50][2],j=0;

array[1][1] = 1;

array[1][0] = 1;

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

{

array[i][0] = array[i-1][1];

array[i][1] = array[i-1][1]+array[i-1][0];

}

我们可以继续找出规律,其实这个就是斐波那切数列数列:

F[N] = F[N-1]+F[N-2];可以继续简化代码。

Pku acm 1458 Common Subsequence 动态规划题目总结(五)

求两个string的最大公共字串,动态规划的经典问题。算法导论有详细的讲解。

下面以题目中的例子来说明算法:两个string分别为:abcfbc和abfca。创建一个二维数组result[][],维数分别是两个字符串长度加一。我们定义result[i][j]表示X i和Y j 的最长子串(LCS).当i或j等于0时,result[i][j]=0. LCS问题存在一下递归式:

result[i][j] = 0 i=0 or j=0

result[i][j] = result[i-1][j-1] X i= =Y j

result[i][j] = MAX(result[i-1][j], result[i][j-1]) X i! =Y j

对于以上例子,算法如下:

含有斜向上的箭头对应的字符是其中的一个lcs。

Java代码的核心部分如下:

for(int i=0;i

result[i][0] = 0;

}

for(int i=0;i

result[0][i] = 0;

}

for(int i=1;i<=length1;i++){

for(int j=1;j<=length2;j++){

if(str1.charAt(i-1)==str2.charAt(j-1))

result[i][j] = result[i-1][j-1]+1;

else

result[i][j] = result[i-1][j]>result[i][j-1]?result[i-1][j]:result[i][j-1];

}

}

System.out.println(result[length1][length2]);

Pku acm 1159 Palindrome 动态规划题目总结(七)

给一个字符串,求这个字符串最少增加几个字符能变成回文,如Ab3bd可以增加2个字符变为回文:Adb3bdA。通过这样的结论可以和最长公共子串联系起来(未证明):S和S' (注:S'是S的反串)的最长公共子串其实一定是回文的。这样我们就可以借助lcs来解决该题,即用s的长度减去lcs的值即可。核心的Java代码为:

total-LCS(string,new StringBuffer(string).reverse().toString());

//函数LCS返回两个string的lcs的长度

Pku acm 1080 Humman Gene Function 动态规划题目总结(八)

这是一道比较经典的DP,两串基因序列包含A、C、G、T,每两个字母间的匹配都会

相关文档
最新文档