问题:
给你一个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 << "最优路径为 "<
结果: