动态规划法 ——多段图的最短路径问题——单向TSP

问题: 
给你一个n行m列的整数矩形,从第一列任何一个位置出发每次往右,右上或右下走一格,最终到达最后一列。要求经过的整数之和最小,整个矩形是环形的,即第一行的上一行是最后一行,最后一行的下一行是第一行,输出路径上每列的行号,多解时输出字典序最小的。 
分析: 
每一列就是一个状态,这个状态是由前一列的右上,右,右下得到的,要得到每个状态的最小值,只需比较右上,右,右下的最小值就好了。

#define INF 100

#include
#include
using namespace std;

int main()
{
	int d[INF][INF], next[INF][INF] = { 0 };
	int a[][100] =
	{
		{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}
	};
	int ans = INF,first=0;
	int i, j,k,n=6,m=5,v;
	memset(d, INF, sizeof(d));
	for (j = n - 1; j >= 0; j--) {  //j表示列,从第n列倒推
		for (i = 0; i < m; i++) {
			if (j == n - 1) {
				d[i][j] = a[i][j];
			}
			else {
				int row[3] = { i,i - 1,i + 1 };
				if (i == 0) {
					row[1] = m - 1;
				}
				if (i == m - 1) {
					row[2] = 0;
				}
				sort(row, row + 3);  //排序使结果相同时,小的排在前面,字典序最小
				for (k = 0; k < 3; k++) {
					v = d[row[k]][j + 1] + a[i][j];   //第j列第i行的下一个row[k]行,j+1列,选出下一个最小的值,用next[]记录row[k]
					if (d[i][j] > v) {
						d[i][j] = v;
						next[i][j] = row[k];
					}
				}
			}
			if (j == 0 && d[i][j] < ans) {
				ans = d[i][j];   //ans是最小的权值
				first = i;  //记录最优值从第几行开始
			}
		}
	}
	cout << "最优路径为 "<

结果:

动态规划法 ——多段图的最短路径问题——单向TSP_第1张图片

你可能感兴趣的:(动态规划法 ——多段图的最短路径问题——单向TSP)