北大ACM1163 - The Triangle (枚举法&备忘录法&动态规划)

1.1.1           枚举法

该问题我使用了枚举法、备忘录法、动态规划法主要是对三种算法进行比较。

任何选择的问题,都可以通过穷举所有可能性,然后从中选择适合的项,这就是枚举法。枚举法是自顶向下,一般也会有递归公式。

设h为Triangle 的高度,v[i,j]为点(i,j)的数字值,sum[i,j]表示到从底到点(i,j)的所有路径中的最大和

运行结果

Time Limit Exceeded

 

根据题目给出的例题,GetSum共执行了31次,而点一共15个,所以有些点在计算sum时,进行了重复计算。

备忘录法就是对枚举法的改进,备忘录法也是自顶向下。

 

代码下载

http://download.csdn.net/detail/gykimo/4948780

1.1.2           备忘录法

将sum初始化为-1,获得某点的sum时,先判断sum是否小于0,如果小于0,说明还没有计算过该点的sum,如果大于等于0,则说明计算过该点的sum,可以直接使用sum。

 

运行结果

Accepted  768K 16MS

 

GetSum共执行了15次,而点一共15个,所以每个点只执行了一次。

1.1.3           动态规划算法

这个问题有动态规划的特点

最优子结构

如果要求出(0,0)点的最大和,可以求出(1,0)和(1,1)的sum。而且这个时候(1,0)和(1,1)的sum是最大的,如果不是最大的,也就是存在另一个路径,使得(1,0)和(1,1)的sum更大,利用剪切法,这存在矛盾,所以(1,0)和(1,1)的sum是最大的。依此类推,该问题存在最优子结构。

递归解(也有叫状态转移公式的)

重叠子问题

根据备忘录法的分析,存在重叠子问题。

 

运行结果

Accepted 768K 16MS

1.1.4           枚举法备忘录法 动态规划对比

具体详见枚举备忘录法最优规划对比
http://blog.csdn.net/gykimo/article/details/8457018

根据《枚举&备忘录法&最优规划》中,动态规划比备忘录法有更高的空间利用效率,我们分析当sum[i][j]计算后,v[i][j]其实根本没有存在的必要了,因为再也不会使用该数据了,那么,我们可以将sum[i][j]充当v[i][j],在初始状态下,sum[i][j]就是v[i][j]的值,当计算出来某点的路径和后,sum[i][j]就表示该点的路径和了。

 

运行结果

Accepted 740K 0MS

确实节省了部分空间,时间上也节省了不少

 

代码

北大ACM1163.DP.optimal.gykimo.cpp

http://download.csdn.net/detail/gykimo/4948959

你可能感兴趣的:(ACM,动态,Triangle,1163)