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

本文介绍了一种解决环形矩阵中寻找从任意起始列到最后一列的最小整数和路径的问题。通过动态规划算法,实现了路径的求解,并确保了在存在多个解时选择字典序最小的路径。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

#define INF 100

#include<algorithm>
#include<iostream>
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 << "最优路径为 "<<first + 1<<" ";  //输出第一列的位置
	for (i = next[first][0], j = 1; j < n; i = next[i][j], j++) {
		cout << i + 1<<" ";
	}
	cout <<endl<< ans;
	return 0;
}

结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值