求矩阵的最大路径的问题

题目描述:有一个m×n的矩阵,现要从左下角走到右上角,并且方向只能是向上或者向右,

现规定一条路径的权值为走此路径所经过的值的和。给定一个矩阵,请找出权值最大的一条

路径。

Example:
2 5 6
3 9 4
7 9 1
所找到的路径为7->9->9->5->6,权值为36。

首先我们来介绍一下动态规划的思想:
   动态规划程序设计中,我们主要利用了问题的两个性质:最优子结构和子问
题重叠。最优子结构指问题的最优解包含了子问题的最优解,它是动态规划方法可
行的理论基础。而一个问题具有子问题重叠性质是指用递归算法自顶向下解这个问
题时,并不总是产生新的子问题,有些子问题被重复求解多次。
  因为最优子结构性质,动态规划求问题最优解时,可以转化为求子问题的最优
解,而对解决过的问题,动态规划则记录它的结果,当再次遇上已解决的问题,就
可以直接利用结果。子问题重叠性质保证了这样做是有意义的。但一般的搜索技术
,对于某个子问题不管是否已经解决过,只要遇上,就会再次对这个子问题进行求
解。
很明显,动态规划与一般搜索技术最大不同的地方就是记录了已求解过的问题
的结果。这里包含了两个方面的内容 :子问题的记录和子问题结果的记录。其中
,子问题的记录是最重要,也是最为复杂的,它就是通常我们所说的状态表示。
通常我们用一个数、一组数或一个向量来实现状态表示。但无论采取什么方法,从
动态规划的原理来看,状态表示要满足两个要求:正确、合理描述子问题和描述的
子问题满足最优子结构性质;从算法实现角度来看,状态表示必须能够用基本数据
结构实现并且能满足空间要求。

现在我们来看上面的这个问题:(path[][]是矩阵的描述)
  状态表示: 用maxpath[i][j]表示走到第i行第j列的最大权值,那么maxpath[i][j]的最优解

包含子问题maxpath[i-1][j]和maxpath[i][j+1]的最优解,然后我们采取倒推法,则可得到我

们的状态转移方程:
maxpath[i][j] = MAX{ maxpath[i-1][j], maxpath[i][j+1] }  + maxpath[i][j];
maxpath[0][n-1] = path[0][n-1];

这样,最大的路径权值可以通过比较底层的分数求得。
一般情况下,我们找到的状态表示应能刻划子问题的特征,困难的是如何找到描述
的子问题能满足最优子结构性质的状态表示,而这一点恰恰是决定该问题能否应用
动态规划方法的重要因素。状态表示1-1描述的问题是正确的,但它不能满足最优
子结构性质,使得无法用它来建立动态规划数学模型。状态分析的过程实际上是分
析问题最优子结构的过程,不同的状态表示正是从不同的角度去试图刻划问题的最
优子结构。只有状态表示描述的子问题能满足最优子结构性质,我们才能在此基础
上正确的建立起动态规划数学模型。

我们看看此题的具体解答:(Java描述)
public class MaxPath
{
 private void print(int path[][])//打印路径
 {
  for(int i=0;i  {
   for(int j=0;j   {
    System.out.print (path[i][j]+" ");
   }
   System.out.println ("");
  }
 }
 public int findMaxPath(int path[][])
 {
  for(int i=path[0].length-2;i>=0;i--)//第一行的值
  {
   path[0][i]+=path[0][i+1];
  }
  for(int i=1;i  {
   path[i][path[i].length-1]+=path[i-1][path[i-1].length-1];
  }
  for(int i=1;i  {
   for(int j=path[i].length-2;j>=0;j--)
   {
    if(path[i-1][j]>=path[i][j+1])
    {
     path[i][j]=path[i][j]+path[i-1][j];
    }
    else
    {
     path[i][j]=path[i][j]+path[i][j+1];
    }
   }
  }
  print(path);
  return path[path.length-1][0];//最后位置的值即为要求的最大权值
 }
 public static void main(String args[])
 {
  int[][] path={{1,2,3,4},
          {5,6,7,8},
          {9,10,11,12},
          {13,14,15,16}
        };
  System.out.println (new MaxPath().findMaxPath(path));
 }
}

你可能感兴趣的:(算法)