动态规划简单例子--象棋步骤
2015-10-02 18:53
330 查看
1.如果问题是由交叠的子问题所构成,我们就可以用动态规划技术来解决它,一般来说,这样的子问题出现在对给定问题求解的递推关系中,这个递推关系包含了相
同问题的更小子问题的解。动态规划法建议,与其对交叠子问题一次又一次的求解,不如把每个较小子问题只求解一次并把结果记录在表中(动态规划也是空间换时间
的),这样就可以从表中得到原始问题的解。
例子:用动态规划算法求解(假设棋盘为n*n,最短路即不能回退)。国际象棋中的车可以水平的或竖直的移动,一个车要从一个棋盘的一角移到对角线的另一角,有多少种最短路径?
我们设定 F[i , j]表示从坐标(0,0)到(i ,j)的方法数(定义F[i , j]的含义,动态规划的一个关键点):
很明显,要走到坐标(i ,j),它的上一步的坐标必定是(i-1 ,j)或者(i ,j-1) (分析动态规划问题的逆向思考)
这样就将问题描述为了交叠子问题:
F[i , j] = F[i -1, j] + F[i , j-1] ( F[i , j] 拆解成更小的交叠的子问题 )
我们要求的是F[n , n]
列出初始边界条件:
F[0 , j] = 1
F[i , 0] = 1
填矩阵的形式:可以按行也可以按列。
典型的动态规划的算法,由最小的边界条件处依次递归.
把矩阵填出来以后也很简单
1 8 36 120 330 792 1716 3432
1 7 28 84 210 462 924 1716
1 6 21 56 126 252 462 792
1 5 15 35 70 126 210 330
1 4 10 20 35 56 84 120
1 3 6 10 15 21 28 36
1 2 3 4 5 6 7 8
车 1 1 1 1 1 1 1
/**
* Copyright 2012, NEWTOUCH Co., Ltd. All right reserved.
*/
package calculation.dynamicprogramming;
同问题的更小子问题的解。动态规划法建议,与其对交叠子问题一次又一次的求解,不如把每个较小子问题只求解一次并把结果记录在表中(动态规划也是空间换时间
的),这样就可以从表中得到原始问题的解。
例子:用动态规划算法求解(假设棋盘为n*n,最短路即不能回退)。国际象棋中的车可以水平的或竖直的移动,一个车要从一个棋盘的一角移到对角线的另一角,有多少种最短路径?
我们设定 F[i , j]表示从坐标(0,0)到(i ,j)的方法数(定义F[i , j]的含义,动态规划的一个关键点):
很明显,要走到坐标(i ,j),它的上一步的坐标必定是(i-1 ,j)或者(i ,j-1) (分析动态规划问题的逆向思考)
这样就将问题描述为了交叠子问题:
F[i , j] = F[i -1, j] + F[i , j-1] ( F[i , j] 拆解成更小的交叠的子问题 )
我们要求的是F[n , n]
列出初始边界条件:
F[0 , j] = 1
F[i , 0] = 1
填矩阵的形式:可以按行也可以按列。
典型的动态规划的算法,由最小的边界条件处依次递归.
把矩阵填出来以后也很简单
1 8 36 120 330 792 1716 3432
1 7 28 84 210 462 924 1716
1 6 21 56 126 252 462 792
1 5 15 35 70 126 210 330
1 4 10 20 35 56 84 120
1 3 6 10 15 21 28 36
1 2 3 4 5 6 7 8
车 1 1 1 1 1 1 1
/**
* Copyright 2012, NEWTOUCH Co., Ltd. All right reserved.
*/
package calculation.dynamicprogramming;
[code] /** * @author aijnec */ public class ChessTest { //棋盘维度 private static int n = 8; //棋盘模型 private long[][] chessBoard = new long ; /** * 构造棋盘矩阵 往格子里填方法数 * */ private void buildChessBoard(){ for(int i=0;i<n;i++){ for(int j=0;j<n;j++){ if(i==0 || j==0){ //边界条件 chessBoard[i][j]=1; //System.out.println("chessBoard["+i+"]"+"["+j+"]="+chessBoard[i][j]); }else{ //子方法递推,最后都回归到了1的加法。 chessBoard[i][j]=chessBoard[i-1][j]+chessBoard[i][j-1]; //System.out.println("chessBoard["+i+"]"+"["+j+"]="+chessBoard[i][j]); } } } } /** * 取得从(0,0)走到对角端点(n,n)的最短方法数 * @return */ public void getPointNum(){ buildChessBoard(); System.out.println("pointNum="+chessBoard[n-1][n-1]); } public static void main(String[] args){ ChessTest test = new ChessTest(); long startTick,endTick; startTick = System.nanoTime(); test.getPointNum(); endTick = System.nanoTime(); System.out.println("process costs "+(endTick-startTick)+" ns"); } } 原文地址:http://aijnecjay.iteye.com/blog/1681380
相关文章推荐
- C#学习日记03---数据类型
- 【BZOJ】【P4291】【PA2015】【Kieszonkowe】【题解】【...】
- maven3常用命令、java项目搭建、web项目搭建详细图解
- leetcode先刷_Unique Paths II
- 第二十五篇:QQ聊天界面
- 小小吐槽
- hdoj 1109 粒子群优化算法(PSO)
- 小小吐槽
- http://www.cnblogs.com/amboyna/archive/2008/03/08/1096024.html
- 100盏灯按倍数开关灯剩余的亮灯数目--约数个数奇偶问题
- STM32 UART编程
- 顺序表的应用
- 国赛个人训练赛 A解题报告
- Double类
- 导航栏和菜单栏的封装
- deeplearning系列(二)自编码神经网络
- 7.Swift翻译教程系列——控制循环的流程
- css-vertical-centering
- [学习笔记]窗口子类化实例
- 进程间、线程间通信方式小结