Pku acm 1163 the Triangle 动态规划题目总结(一)
题目:http://acm.pku.edu.cn/JudgeOnline/problem?id=1163
对于一个有数字组成的二叉树,求由叶子到根的一条路径,使数字和最大,如:
7
3 8
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];
}
}
带有详细注释的代码可以在http://download.csdn.net/user/china8848/获得
Pku acm 1579 Function Run Fun 动态规划题目总结(二)
http://acm.pku.edu.cn/JudgeOnline/problem?id=1579
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 页讲到自底向上的递推,这个例子就非常典
型。总体来说这个题目还是非常简单的,不过这个思想是地道的动态规划。
带有详细注释的代码可以在http://download.csdn.net/user/china8848/获得
Pku acm 2081 Recaman's Sequence 动态规划题目总结(三)
http://acm.pku.edu.cn/JudgeOnline/problem?id=2081
一道很简单的动态规划,根据一个递推公式求一个序列,我选择顺序的求解,即自底向
上的递推,一个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;
}
}
带有详细注释的代码可以在http://download.csdn.net/user/china8848/获得
Pku acm 1953 World Cup Noise 动态规划题目总结(四)
http://acm.pku.edu.cn/JudgeOnline/problem?id=1953
给定一个小于45 的整数n,求n 位2 进制数中不含相邻1 的数的个数。看似简单的一
道题,如果当n=45 时,对2 的45 次方检查,是无法完成的任务。先分析一下这个问题:
N 以1 结尾的个数以0 结尾的个数总和
1 1 1 2
2 1 2 3
3 ⋯ ⋯ ⋯
对于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];可以继续简化代码。
带有详细注释的代码可以在http://download.csdn.net/user/china8848/获得
Pku acm 1458 Common Subsequence 动态规划题目总结(五)
http://acm.pku.edu.cn/JudgeOnline/problem?id=1958
求两个string 的最大公共字串,动态规划的经典问题。算法导论有详细的讲解。
下面以题目中的例子来说明算法:两个string 分别为:abcfbc 和abfca。创建一个二维数
组result[][],维数分别是两个字符串长度加一。我们定义result[i][j]表示Xi和Yj 的最
长子串(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] Xi= =Yj
result[i][j] = MAX(result[i-1][j], result[i][j-1]) Xi! =Yj
对于以上例子,算法如下:
Result[i][j]:
a b c f b a
0 1 2 3 4 5 6
0 0 0 0 0 0 0 0
a 1 0 1 1 1 1 1 1
b 2 0 1 2 2 2 2 2
f 3 0 1 2 2 3 3 3
c 4 0 1 2 3 3 3 3
a 5 0 1 2 3 3 3 4
从最后一个格向上顺着箭头的方向可以找到最长子串的构成,在有箭头组成的线段中,
含有斜向上的箭头对应的字符是其中的一个lcs。
Java 代码的核心部分如下:
for(int i=0;i<length1;i++){
result[i][0] = 0;
}
for(int i=0;i<length2;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]);
带有详细注释的代码可以在http://download.csdn.net/user/china8848/获得
Pku acm 2250 Compromise 动态规划题目总结(六)
http://acm.pku.edu.cn/JudgeOnline/problem?id=2250
这个也是求最长公共字串,只是相比Common Subsequence 需要记录最长公共字串的构
成,此时箭头的标记就用上了,在程序中,用opt[][]存放标记,0 表示朝向左上方,1 表示
指向上,-1 表示指向左。result[][]存放当前最大字串长度。在求最优解时,顺着箭头从
后向前寻找公共字串的序号,记录下来,输出即可。该算法在算法导论中有详细的讲解。
带有详细注释的代码可以在http://download.csdn.net/user/china8848/获得。
Pku acm 1159 Palindrome 动态规划题目总结(七)//1141
http://acm.pku.edu.cn/JudgeOnline/problem?id=1159
给一个字符串,求这个字符串最少增加几个字符能变成回文,如Ab3bd 可以增加2 个字
符变为回文:Adb3bdA。通过这样的结论可以和最长公共子串联系起来(未证明):S 和S'
(注:S'是S 的反串)的最长公共子串其实一定是回文的。这样我们就可以借助lcs 来解决该
题,即用s 的长度减去lcs 的值即可。核心的Java 代码为:
total-LCS(string,new StringBuffer(string).reverse().toString());
//函数LCS 返回两个string 的lcs 的长度
带有详细注释的代码可以在http://download.csdn.n