典型的动态规划问题,类似于数字三角形的感觉。要求字典序路径。
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <queue>
#include <map>
using namespace std;
int v[110][110],dp[110][110],path[110][110];
int m,n;
int main(){
while(scanf("%d%d",&m,&n) == 2){
for(int i=1; i<=m; i++)
for(int j=1; j<=n; j++)
scanf("%d",&v[i][j]);
memset(dp, 0x3f, sizeof(dp));
for(int i=1; i<=m; i++)
dp[i][n] = v[i][n];
for(int j=n-1; j>0; j--){
for(int i=1; i<=m; i++){
int row[3] = {i, i-1, i+1};
if(i == 1) row[1] = m;
else if(i == m) row[2] = 1;
sort(row, row + 3);//!保证字典序
for(int k=0; k<3; k++){
int tmp = dp[row[k]][j+1] + v[i][j];
if(dp[i][j] > tmp){
dp[i][j] = tmp;
path[i][j] = row[k];//记录路径
}
}
}
}
int ans = 0x3f3f3f3f,now = 1;
for(int i=1; i<=m; i++){
if(ans > dp[i][1]){
ans = dp[i][1];
now = i;
}
}
cout << now;
for(int i=path[now][1],j=2; j<=n; i=path[i][j], j++)//打印路径
cout << " " << i;
cout << endl;
cout << ans << endl;
}
return 0;
}