zoukankan      html  css  js  c++  java
  • 第九章(三)多阶段决策问题

    多段图的最短路

    给一个M行N列的整数矩阵,从第一列任何一个位置出发,每次往右,右上和右下走一格,最终达到最后一列。要求经过的整数之和最小,整个矩阵是环形的即第一行的上一行是最后一行,最后一行的下一行是第一行,输出路径上每列的行号,多解时输出字典序最小的

    思路:很明显每一列是一个阶段。(阶段)

    需要填的表是距离d(i,j)这一块到达最后一列的最短路径长度。(衡量标准)d(i,j)=min(d(i+1,j+1),d(i-1,j+1),d(i,j+1))

    自底向上思考,最后一列为边界,此时这个距离d(i,n-1)应该就是矩阵本身的值a[i][n-1]。(边界条件)

     1 /**
     2      * 给一个M行N列的整数矩阵,从第一列任何一个位置出发,
     3      * 每次往右,右上和右下走一格,最终达到最后一列。
     4      * 要求经过的整数之和最小,整个矩阵是环形的即第一行的上一行是最后一行,
     5      * 最后一行的下一行是第一行,
     6      * 输出路径上每列的行号,多解时输出字典序最小的
     7      */
     8     public static void test(int[][]a) {
     9         int m=a.length,n=a[0].length;
    10         int[][]d=new int[m][n];//d(i,j)记录最短的整数之和
    11         int[][]s=new int[m][n];//记录(i,j)的下一列对应的行数
    12         for(int i=0;i<m;i++) d[i][n-1]=a[i][n-1];//初始状态
    13         int ans=2000,start=-1;
    14         for(int i=0;i<m;i++) {
    15             for(int j=n-2;j>=0;j--) {
    16                 int[]k= {i,(i+1)%m,(i-1+m)%m};
    17                 Arrays.sort(k);//按照字典序
    18                 d[i][j]=a[k[0]][j+1]+a[i][j];
    19                 s[i][j]=k[0];
    20                 for(int z=0;z<3;z++) {
    21                     int temp=a[k[z]][j+1]+a[i][j];
    22                     if(temp<d[i][j]) {
    23                         d[i][j]=temp;
    24                         s[i][j]=k[z];
    25                     }
    26                 }
    27                 if(j==0&&ans>d[i][j]) {//找出第一列最小的
    28                         ans=d[i][j];
    29                         start=i;
    30                 }
    31             }
    32         }
    33         System.out.println(start+1);
    34         for(int i=s[start][0],j=0;j<n-1;i=s[i][j],j++) {
    35             System.out.println(s[i][j]+1);
    36         }
    37     }
    38     public static void main(String[] args) {
    39         int[][]a=new int[5][6];
    40         Scanner scn=new Scanner(System.in);
    41         for(int i=0;i<5;i++) {
    42             for(int j=0;j<6;j++) {
    43                 a[i][j]=scn.nextInt();
    44             }
    45         }
    46         test(a);
    47     }

    Input:

    3 4 1 2 8 6
    6 1 8 2 7 4
    5 9 3 9 9 5
    8 4 1 3 2 6

    Output:

    1
    2
    1
    5
    4
    5

  • 相关阅读:
    OpenStack 数据库操作 demo
    python 实现获取电脑IP、主机名、Mac地址
    openvswitch BFD 简介
    Python 获取主机名
    OpenvSwitch完全使用手册
    ovs datapath笔记
    openstack 实用命令
    表示数值的字符串 牛客网 剑指Offer
    反转单词顺序列 牛客网 剑指Offer
    第一个只出现一次字符的位置 牛客网 剑指Offer
  • 原文地址:https://www.cnblogs.com/code-fun/p/12624037.html
Copyright © 2011-2022 走看看