DP动态规划解矩阵中最小路径(动态规划学习之二) z


 
动态规划:动态规划所处理的问题是一个多阶段决策问题,一般由初始状态开始,通过对中间阶段决策的选择,达到结束状态。这些决策形成了一个决策序列,同时确定了完成整个过程的一条活动路线(通常是求最优的活动路线),一般要经过以下几个步骤:
    (1)划分阶段:按照问题的时间或空间特征,把问题分为若干个阶段。在划分阶段时,注意划分后的阶段一定要是有序的或者是可排序的,否则问题就无法求解。
    (2)确定状态和状态变量:将问题发展到各个阶段时所处于的各种客观情况用不同的状态表示出来。当然,状态的选择要满足无后效性。
    (3)确定决策并写出状态 转移方程:因为决策和状态转移有着天然的联系,状态转移就是根据上一阶段的状态和决策来导出本阶段的状态。所以如果确定了决策,状态转移方程也就可写出。但事实上常常是反过来做,根据相邻两段各状态之间的关系来确定决策。
    (4)寻找 边界条件:给出的状态转移方程是一个递推式,需要一个递推的终止条件或边界条件。
使用动态规划求解问题,最重要的就是确定动态规划三要素:问题的 阶段,每个阶段的 状态以及从前一个阶段转化到后一个阶段之间的 递推关系。递推关系必须是从次小的问题开始到较大的问题之间的转化,从这个角度来说,动态规划往往可以用递归程序来实现,不过因为递推可以充分利用前面保存的子问题的解来减少重复计算,所以对于大规模问题来说,有递归不可比拟的优势,这也是动态规划算法的核心之处。确定了动态规划的这三要素,整个求解过程就可以用一个 最优决策表来描述。
 
适用动态规划的问题必须满足最优化原理和无后效性。一般来说,动态规划将原来具有指数级复杂度的搜索算法改进成了具有多项式时间的算法。其中的关键在于 解决冗余,这是动态规划算法的根本目的。动态规划实质上是一种以空间换时间的技术,它在实现的过程中,不得不存储产生过程中的各种状态,所以它的空间复杂度要大于其它的算法。
 
这里有一个比较经典的利用动态规划解决矩阵中最小路径问题的例子(来源于ACM竞赛习题)。

The Problem

Given an tex2html_wrap_inline352 matrix of integers, you are to write a program that computes a path of minimal weight. A path starts anywhere in column 1 (the first column) and consists of a sequence of steps terminating in column n (the last column). A step consists of traveling from column i to column i+1 in an adjacent (horizontal or diagonal) row. The first and last rows (rows 1 and m) of a matrix are considered adjacent, i.e., the matrix ``wraps'' so that it represents a horizontal cylinder. Legal steps are illustrated below.

 500)this.width=500;" border=0>

The weight of a path is the sum of the integers in each of the n cells of the matrix that are visited.

For example, two slightly different tex2html_wrap_inline366 matrices are shown below (the only difference is the numbers in the bottom row).

 

The minimal path is illustrated for each matrix. Note that the path for the matrix on the right takes advantage of the adjacency property of the first and last rows.

The Input
500)this.width=500;" border=0>

The input consists of a sequence of matrix specifications. Each matrix specification consists of the row and column dimensions in that order on a line followed by tex2html_wrap_inline376 integers where m is the row dimension and n is the column dimension. The integers appear in the input in row major order, i.e., the first n integers constitute the first row of the matrix, the second n integers constitute the second row and so on. The integers on a line will be separated from other integers by one or more spaces. Note: integers are not restricted to being positive. There will be one or more matrix specifications in an input file. Input is terminated by end-of-file.

For each specification the number of rows will be between 1 and 10 inclusive; the number of columns will be between 1 and 100 inclusive. No path's weight will exceed integer values representable using 30 bits.

The Output

Two lines should be output for each matrix specification in the input file, the first line represents a minimal-weight path, and the second line is the cost of a minimal path. The path consists of a sequence of n integers (separated by one or more spaces) representing the rows that constitute the minimal path. If there is more than one path of minimal weight the path that is lexicographically smallest should be output.

Sample Input

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

Sample Output

1 2 3 4 4 5
16
1 2 1 5 4 5
11
1 1
19

我的详细代码如下:
 
 

#include "iostream"
#include "fstream"
#include "vector"

using namespace std;

int matrix[100][100];
int matrix_min[100][100];
int matrix_row[100][100]; //row of all


int columns =0;//number of column or row

int rows = 0;

int MinMatrix(int i,int j)
{
        if(j == columns) return 0;

        if(matrix_min[i][j] == -1)
        {
                int min_matrix1=MinMatrix((i-1+rows)%rows,j+1);
                int min_matrix2=MinMatrix((i+rows)%rows,j+1);
                int min_matrix3=MinMatrix((i+1+rows)%rows,j+1);

                int temp_min = min_matrix1;
                matrix_row[i][j] = (i-1+rows)%rows;
                matrix_min[i][j]=min_matrix1+matrix[i][j];

                if(min_matrix2 < temp_min)
                {
                        temp_min = min_matrix2;
                        matrix_row[i][j] = (i+rows)%rows;
                        matrix_min[i][j]=min_matrix2+matrix[i][j];
                }

                if(min_matrix3 < temp_min)
                {
                        temp_min = min_matrix3;
                        matrix_row[i][j] = (i+1+rows)%rows;
                        matrix_min[i][j]=min_matrix3+matrix[i][j];
                }
        }
        return matrix_min[i][j];
}

int main()
{
        fstream fin("matrix.txt");
        fin>>rows>>columns;
        int i,j;

        //read matrix

        for(i=0;i<rows;i++)
        {
                for(j=0;j<columns;j++)
                {
                        fin>>matrix[i][j];
                        matrix_min[i][j] = -1;
                }
        }

        int sum = 0;
        int entry = -1;
        sum = MinMatrix(0,0);
        entry = 0;
        for(i=0;i<rows;i++)
        {
                int temp = MinMatrix(i,0);
                if(sum > temp)
                {
                        sum = temp;
                        entry = i;
                }
        }

        cout<<"the min of the path is :"<<sum<<endl;
        cout<<"the path is"<<entry+1;
        int old_row = entry;
        for(i=0;i<columns-1;i++)
        {
                int next_row = matrix_row[old_row][i];
                old_row = next_row;
                cout<<"->"<<next_row+1;
        }
        cout<<endl;
        return 0;
}


<script type="text/javascript"> </script> <script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"> </script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值