本文借鉴了朋友的文章,做了一点润色。
文章链接:https://blog.csdn.net/qq_27070117/article/details/79819352
有一道算法题, 如下所示, 有一数字矩阵, 从左上走到右下, 只能向下或向右走, 求走到右下角所经过的数字的和的最大值以及经过的路径.
1 2 3 4
5 6 9 8
9 1 0 1
2 3 4 5
这道题就用到了动态规划算法, 那么什么是动态规划算法呢?我理解的是:“调动所有的群众数字,参与到规划方案中”。所有的数字都是要进行相同的运动,最后根据算法中的筛选条件,进行取舍,抽象概括就是动态规划了。
解这道动态规划题的核心就是要画出对应的平面直角坐标系,正所谓数无形时少直觉,形少数时难入微,有了坐标系,可以更好更直观的给出解决方法。图中的每个点都要记住以下几个值,该点的坐标,值,和到该点的最大路径权重值的点。这是非常重要的。我们通过遍历,调动每一个群众数字参与运算,每个数字都记录了到达它的上一个节点。这样就像一条链表一样串起来了一条路径了。获取每一个节点,将都能得到这个节点的路径,最大最小,根据题目变化。这也从另外一个角度说出了动态路径规划的缺点。调动性太强了,一点事情就要所有人都参与,时间复杂度和空间复杂度都太高。
聊完了思想,下面是该思想的java代码:
public class MyDynamicAlogrithm {
//通过修改mNodes数组中的数据来进行结果的存储
public static Node mNodes[][] = {
{new Node(1), new Node(2), new Node(3), new Node(4)},
{new Node(5), new Node(6), new Node(9), new Node(8)},
{new Node(9), new Node(1), new Node(0), new Node(1)},
{new Node(2), new Node(3), new Node(4), new Node(5)}
};
public static void main(String args[]) {
for (int x = 0; x < mNodes.length; x++) {
for (int y = 0; y < mNodes[0].length; y++) {
//先获取这次要确定确定路径权值的节点
Node node = mNodes[x][y];
node.x_axis = x;
node.y_axis = y;
node.selfValue = mNodes[x][y].selfValue;
Node lastNode = null;
if (x == y & x == 0) {
node.selfValue = 1;
node.totalWeight = 1;
node.lastBestNode = lastNode;
} else {
if (x == 0) {
lastNode = mNodes[0][y - 1];
} else if (y == 0) {
lastNode = mNodes[x - 1][0];
} else {
Node leftNode = mNodes[x - 1][y];
Node downNode = mNodes[x][y - 1];
if (leftNode.totalWeight > downNode.totalWeight) {
lastNode = leftNode;
} else {
lastNode = downNode;
}
}
}
//通过遍历每一个点,给它设置最大的路径权重。同时设置路径中的上一个点,这样遍历到最后一个点,将得到一条确定的路线
node.lastBestNode = lastNode;
if (lastNode != null) {
node.totalWeight = node.selfValue + lastNode.totalWeight;
}
}
}
//输出结果
Node pathNode = mNodes[3][3];
System.out.println("到最后一个点的最大的路径权重值是:" + pathNode.totalWeight);
StringBuilder stringBuilder = new StringBuilder();
while (pathNode.lastBestNode != null) {
stringBuilder.append("(");
stringBuilder.append(pathNode.x_axis);
stringBuilder.append(",");
stringBuilder.append(pathNode.y_axis);
stringBuilder.append(")");
stringBuilder.append("<------");
pathNode = pathNode.lastBestNode;
}
stringBuilder.append("(");
stringBuilder.append(pathNode.x_axis);
stringBuilder.append(",");
stringBuilder.append(pathNode.y_axis);
stringBuilder.append(")");
System.out.println("最大路径是:" + stringBuilder);
}
public static class Node {
public int x_axis;
public int y_axis;
public Node lastBestNode;
public int selfValue;
public int totalWeight;
public Node(int value) {
this.selfValue = value;
}
}
}