动态规划demo

本文介绍了如何使用动态规划算法解决一个寻找数字矩阵中从左上角到右下角路径最大和的问题。动态规划核心是建立坐标系并记录每个点的值、坐标和最大路径权重。通过遍历矩阵,构建路径并优化时间复杂度和空间复杂度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文借鉴了朋友的文章,做了一点润色。

文章链接: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;
        }
    }

}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值