类型特点
线性DP一般是用来解决以某种规律走迷宫,或最短路径权值的问题
其实也是按模板套(如果不清楚模板,建议大家先看上一篇我的有关动态规划的博客点此跳转,如果还想了解另一类动态规划问题可以看我的这篇文章决策型动态规划)
下面我将展示两个例题来演示这类动态规划问题
例题1
p1216 数字三角形
题目描述
观察下面的数字金字塔。
写一个程序来查找从最高点到底部任意处结束的路径,使路径经过数字的和最大。每一步可以走到左下方的点也可以到达右下方的点。
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
在上面的样例中,从 7→3→8→7→5 的路径产生了最大
输入格式
第一个行一个正整数 r,表示行的数目。
后面每行为这个数字金字塔特定行包含的整数。
输出格式
单独的一行,包含那个可能得到的最大的和。
思路:
先构建一个二维数组有n行,每行只有i列,对于每一个子问题,我们只需往下层的左或右走(转化为数组是下一行同一列,或下一列下一行)
并取两种方案(还得加上当前的权值)中的最大值即可。
这里我们从下往上走,防止数组越界
1.确定状态
int[][] dp=new int[n+1][n+1];//表示从最后一行中的某一列到第i行j列时当前的最大形式
2.初始化
//初始化最后一行
for (int i = 1;i<=n;i++) {//每行只有i个
dp[n][i]=arr[n][i];
}
3.转移方程确定
for (int i = n-1; i>0; i–) {
for(int j=1;j<=i;j++) {
dp[i][j]=Math.max(arr[i][j]+dp[i+1][j],dp[i+1][j+1]+arr[i][j]);
}
}
(这里的arr[i][j]是当前的权值)
4.边界条件
无
题1代码
package competion2016;
import java.util.Scanner;
public class 数字三角形 {
public static void main(String[] args) {
Scanner scanner =new Scanner(System.in);
int n=scanner.nextInt();
int[][] arr=new int[n+1][n+1];
int[][] dp=new int[n+1][n+1];//表示到第i行j列时当前的最大形式
for (int i = 1; i <= n; i++) {//n行
for (int j = 1; j <=i; j++) {//每行只有i个
arr[i][j]=scanner.nextInt();
}
}
//初始化最后一行
for (int i = 1;i<=n;i++) {//每行只有i个
dp[n][i]=arr[n][i];
}
for (int i = n-1; i>0; i--) {
for(int j=1;j<=i;j++) {
dp[i][j]=Math.max(arr[i][j]+dp[i+1][j],dp[i+1][j+1]+arr[i][j]);
}
}
System.out.println(dp[1][1]);
}
}
题一方法总结
我们在递推的过程中,实际上是在填一个dp表,这个dp表的规模实际上就和数组三角型对应的arr数组的大小一样,每次我们将递推的数据填入对应节点的dp表中,而这个dp表最后一个元素往往就是我们所要的解
这也就是动态规划的一种常用方法=打表法=