动态规划小例子
来源:互联网 发布:棋牌游戏网站源码 编辑:程序博客网 时间:2024/04/30 12:59
上图给出了一个数字三角形。从三角形的顶部到底部有很多条不同的路径。对于每条路径,把路径上面的数加起来可以得到一个和,和最大的路径称为最佳路径。你的任务就是求出最佳路径上的数字之和。
注意:路径上的每一步只能从一个数走到下一层上和它最近的左边的数或者右边的数。
输入样例
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
输出样例
30
这道题目可以用递归的方法解决。基本思路是:
以D(r, j)表示第r行第 j个数字(r,j都从1开始算),以MaxSum(r,j)代表从第 r行的第 j个数字到底边的最佳路径的数字之和,则本题是要求MaxSum(1, 1) 。
从某个D(r,j)出发,显然下一步只能走D(r+1, j)或者D(r+1,j+1)。如果走D(r+1, j),那么得到的MaxSum(r,j)就是MaxSum(r+1, j) + D(r, j);如果走D(r+1,j+1),那么得到的MaxSum(r, j)就是MaxSum(r+1,j+1) + D(r, j)。所以,选择往哪里走,就看MaxSum(r+1, j)和MaxSum(r+1,j+1)哪个更大了。
上面的程序,效率非常低,在N值并不大,比如N=100的时候,就慢得几乎永远算不出结果了。
为什么会这样呢?是因为过多的重复计算。
我们不妨将对MaxSum函数的一次调用称为一次计算。那么,每次计算MaxSum(r,j)的时候,都要计算一次MaxSum(r+1, j+1),而每次计算MaxSum(r,j+1)的时候,也要计算一次MaxSum(r+1, j+1)。重复计算因此产生。
这种将一个问题分解为子问题递归求解,并且将中间结果保存以避免重复计算的办法,就叫做“动态规划”。动态规划通常用来求最优解,能用动态规划解决的求最优解问题,必须满足,最优解的每个局部解也都是最优的。以上题为例,最佳路径上面的每个数字到底部的那一段路径,都是从该数字出发到达到底部的最佳路径。
实际上,递归的思想在编程时未必要实现为递归函数。在上面的例子里,有递推公式:
因此,不需要写递归函数,从aMaxSum[N-1]这一行元素开始向上逐行递推,就能求得aMaxSum[1][1]的值了。
code
package com.wyy.core.util;import java.io.PrintWriter;import java.util.Scanner;public class Main { static Scanner scin = new Scanner(System.in); static PrintWriter scout = new PrintWriter(System.out); static int[][] all = new int[110][110]; static int[][] mem = new int[110][110]; public static void main(String[] args) { int size = scin.nextInt(); for (int i = 1; i <= size; i++) { for (int j = 1; j <= i; j++) { all[i][j] = scin.nextInt(); } } scout.println(MaxSum(size, 1, 1)); for (int i = 1; i <= size; i++) { for (int j = 1; j <= i; j++) { scout.print(mem[i][j] + " "); } scout.println(); } scout.flush(); scout.println("-----------------------------------------------"); mem = new int[110][110]; for (int j = 1; j <= size; j++) mem[size][j] = all[size][j]; for (int i = size; i > 1; i--) { for (int j = 1; j < i; j++) { if (mem[i][j] > mem[i][j + 1]) mem[i - 1][j] = mem[i][j] + all[i - 1][j]; else mem[i - 1][j] = mem[i][j + 1] + all[i - 1][j]; } } scout.println(mem[1][1]); for (int i = 1; i <= size; i++) { for (int j = 1; j <= i; j++) { scout.print(mem[i][j] + " "); } scout.println(); } scout.flush(); scout.close(); } public static int MaxSum(int size, int r, int j) { if (r == size) { mem[r][j] = all[r][j]; return all[r][j]; } if (mem[r + 1][j] == 0) { mem[r + 1][j] = MaxSum(size, r + 1, j); } if (mem[r + 1][j + 1] == 0) { mem[r + 1][j + 1] = MaxSum(size, r + 1, j + 1); } if (mem[r + 1][j] > mem[r + 1][j + 1]) { System.out.println("MaxSum(" + r + ", " + j + ")=" + (mem[r + 1][j] + all[r][j])); return mem[r + 1][j] + all[r][j]; } System.out.println("MaxSum(" + r + ", " + j + ")=" + (mem[r + 1][j + 1] + all[r][j])); return mem[r + 1][j + 1] + all[r][j]; }}
动态规划解题的一般思路
- 动态规划小例子
- 动态规划例子
- python 动态规划例子
- 动态规划例子
- 动态规划入门例子
- 动态规划小题目;
- 动态规划小入门
- 动态规划小示例
- 动态规划小练习
- 动态规划小入门
- 动态规划(详解 带例子)
- 动态规划01背包例子
- 动态规划的经典例子
- 动态规划的一个例子
- 动态的小例子
- 从一个小例子来初步认识递归,迭代,动态规划。
- 看动态规划小感
- JDK动态代理小例子
- TI8168 PCIe多路高清显卡方案
- OMAP3630 Linux I2C总线驱动分析
- OpenGL 学习资源
- 你想建设一个能承受500万PV/每天的网站吗?服务器每秒要处理多少个请求才能应对?
- Office控件
- 动态规划小例子
- 如何设置socket的Connect超时
- yuv420和rgb24互相转换
- js优化技术---记忆(memoization)实例测试
- UIViewController的 dismissViewControllerAnimated:completion:方法
- ffmpeg开发出现的问题(四) ftp/rstp/ts 流输出
- ORACLE老版本下载地址
- 员工评语的隐含意
- busybox启用telnetd功能