116单向TSP

来源:互联网 发布:什么租房软件最好 编辑:程序博客网 时间:2024/05/16 05:43

(原题详见UVa116)

本文主要包含以下内容:

1.数学模型的建立

2.递推伪代码的推导

3.代码实现

4.总结


关键字:动态规划


1.数学模型的建立

这是一道典型的动态规划题目。

定义d[i][j]表示在矩阵i,j处是最小和。那么d[i][j]可能由三种状态转移而来d[i-1][j-1]   d[i][j-1]      d[i+1][j-1]

状态转移方程如下:

           d[i][j] = min{d[i-1][j-1]  , d[i][j-1]  , d[i+1][j-1]}+c[i][j];             c[i][j]为矩阵在i,j处的值


2.递推伪代码的推导:

一问:递归起始状态是?

            d[0][0]    d[1[0]    d[2][0] ........d[r-1][0]       (  r表示矩阵的行数,c表示矩阵的列)

            接下来计算:

             d[0][1]    d[1[1]    d[2][1] ........d[r-1][1] 

   

            因此i为内层循环,j为外层循环

            i:0->r-1           j:1->c-1


递推伪代码如下:

        for i:0->r-1    d[i][0] = c[i][0]

        for   j:1->c-1

              do i:0->r-1

                if i==0    i-1=>r-1

                if i==r-   1 i+1=>0

                d[i][j] = min{d[i-1][j-1]  , d[i][j-1]  , d[i+1][j-1]}+c[i][j]; 


3.具体实现代码

#include<iostream>using namespace std;int main(){int row,col;cin >> row;cin >> col;int c[10][100];int f[10][100];//int route[10][100];for (int i = 0; i < row; i++)for (int j = 0; j < col; j++)cin >> c[i][j];memset(f, 0, sizeof(f));for (int i = 0; i < row; i++)f[i][0] = c[i][0];//dpfor (int j = 1; j < col; j++)for (int i = 0; i < row; i++){int x, y,z;if (i == 0)  x = f[row - 1][j - 1]+c[i][j];else  x = f[i - 1][j - 1] + c[i][j];if (i == row - 1) y = f[0][j - 1] + c[i][j];else y = f[i + 1][j - 1] + c[i][j];z = f[i][j - 1] + c[i][j];f[i][j] = x; //if (i == 0) route[i][j] = row - 1;//route[i][j] = i - 1;if (y < f[i][j]){f[i][j] = y;//if (i == row - 1)route[i][j] = 0;//route[i][j] = i + 1;}if (z < f[i][j]){f[i][j] = z;//route[i][j] = i ;}}int min = 0;for (int i = 1; i < row; i++)if (f[i][col - 1] < f[min][col - 1])min = i;cout << f[min][col - 1]<<endl;int route[100];route[col - 1] = min+1;int r = min;for (int j = col - 1; j > 0; j--)for (int i = 0; i < row; i++){if (f[r][j] == f[i][j - 1] + c[r][j]){route[j - 1] = i+1;//cout << i+1 << " ";r = i;break;}}for (int j = 0; j < col; j++)cout << route[j] << " ";cout << endl;return 0;}

4.总结

要想一次性的写出正确的代码,最好在正是写代码之前先写好伪代码。先写伪代码先写伪代码先写伪代码。重要的事情说三遍。

写伪代码有以下好处:

          方便自己理清思路

          方便查找逻辑上的错误


0 0
原创粉丝点击