UVa 116
水题,简单的DAG的扩展,关于矩阵是循环的,利用模运算解决就好,字典序就单独开一个数组来记录
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
#include <vector>
using namespace std;
const int maxm= 15;
const int maxn= 105;
const int INF= 0x3f3f3f3f;
int M[maxm][maxn], nxt[maxm][maxn], dp[maxm][maxn];
int main()
{
int m, n;
while (2== scanf("%d %d", &m, &n)){
for (int i= 0; i< m; ++i){
for (int j= 1; j<= n; ++j){
scanf("%d", &M[i][j]);
}
}
// dp[i][j]= min(u, d, r)+M[i][j]
// u= dp[(i+m-1)%m][j+1]
// d= dp[(i+m+1)%m][j+1]
int ans= INF;
int s= -1;
for (int j= n; j> 0; --j){
for (int i= 0; i< m; ++i){
if (n== j){
dp[i][j]= M[i][j];
}
else{
int o[3]= {(i+m-1)%m, i, (i+m+1)%m};
int x= INF;
for (int k= 0; k< 3; ++k){
if (dp[o[k]][j+1]< x){
x= dp[o[k]][j+1];
nxt[i][j]= o[k];
}
else if(dp[o[k]][j+1]== x){
nxt[i][j]= min(o[k], nxt[i][j]);
}
}
dp[i][j]= x+M[i][j];
}
if (j== 1 && dp[i][j]< ans){
ans= dp[i][j];
s= i;
}
}
}
printf("%d", s+1);
for (int i= nxt[s][1], j= 2; j<= n; i= nxt[i][j++]){
printf(" %d", i+1);
}
printf("\n%d\n", dp[s][1]);
}
}