《算法导论》中动态规划习题15-6--在棋盘上移动

来源:互联网 发布:魔乐科技java课堂笔记 编辑:程序博客网 时间:2024/05/17 01:05
问题描述:假设有一张n*n个方格的棋盘以及一个棋子,必须根据以下的规则把棋子从棋盘的底边移动到棋盘的顶边,在每一步你可以把棋子移动到三个方格中的一个:
1、正上方的方格。
2、左上方的方格(只能当这个棋子不在最左列的时候)
3、右上方的方格(只能当这个棋子不在最右列的时候)
每次从方格x移动到方格y,会得到p(x,y)块钱。已知所有(x,y)的p(x,y),只要从x到y的移动是合法的。不要假设p(x,y)是正值。
请给出一个计算移动方式集合的算法,把棋子从棋盘底边的某个地方移动到棋盘顶边的某个地方,同时收集尽可能多的钱。你的算法可以自由选择底边的任意方格作为起始点,顶边上的任意方格作为目的点,来最大化一路上收集到的钱数。你的算法的执行时间是多少?
 
解答:这个问题可以用动态规划来解决,对表格从底向上从左向右进行一次扫描,把把过程中受益最的记录下来就可以了。文字功底有限,画表格来说明,如下:
 
 
  3   -6   5   7  42  24   -20  41   84 -50  56  -54   5  -25  8  5   74  10   8  45  -9  -21  12  62    4
                
                各个方格上的钱
 
由上面的表格从底向上从左向右,一一扫描出下面可以到达此方格的方格中最大的那个与本身方格值相加,并记录下来。如下:
    169   160    204    206   241    166   122    132    199   65    142   32   91   82   115   -4   86   72   70  107   -9  -21   12  62  4
 
result[i][j]= max(左下角值,正下值,右下角值);
               动态规划记录表
 
所以答案为:241 = 62+45+8+84+42
 
代码实现如下:

 
package csdn.jtlyuan;public class MaxMoney {public int getMaxMoney(int[][] a,int n){int max=0;int[][] result = new int[n][n];for(int i=0;i<n;i++){result[n-1][i]=a[n-1][i];}for(int i=n-2;i>=0;i--){for(int j=0;j<n;j++){result[i][j]=a[i][j]+maxRs(result,i,j,n);//记录来到这里中最大收益}}for(int i=0;i<n;i++){//求顶层的最大收益if(max<result[0][i]){max=result[0][i];}}System.out.println("记录表格如下:");print(result);return max;}private int maxRs(int[][] rs,int i, int j,int n) {//求下一层的最小值if(j==0){return rs[i+1][j]>rs[i+1][j+1]?rs[i+1][j]:rs[i+1][j+1];}else if(j==n-1){return rs[i+1][j]>rs[i+1][j-1]?rs[i+1][j]:rs[i+1][j-1];}else{int max = rs[i+1][j]>rs[i+1][j-1]?rs[i+1][j]:rs[i+1][j-1];return max>rs[i+1][j+1]?max:rs[i+1][j+1];}}void print(int[][] rs){//打印二维数组for(int i=0;i<rs.length;i++){for(int j=0;j<rs.length;j++){System.out.print(rs[i][j]+" ");}System.out.println();;}}public static void main(String[] args) {int[][] a = {{3,-6,5,7,42},{24,-20,41,84,-50},{56,-54,5,-25,8},{5,74,10,8,45},{-9,-21,12,62,4}};MaxMoney mm = new MaxMoney();System.out.println("原来的表格如下:");mm.print(a);System.out.println("最大值为:"+mm.getMaxMoney(a, a.length));}}



测试结果:
原来的表格如下:
3 -6 5 7 42
24 -20 41 84 -50
56 -54 5 -25 8
5 74 10 8 45
-9 -21 12 62 4
记录表格如下:
169 160 204 206 241
166 122 132 199 65
142 32 91 82 115
-4 86 72 70 107
-9 -21 12 62 4
最大值为:241