一道dp, 和那个数字三角有点像,只不过要记录路径。用一个nex数组(使用next会编译错误)来记录(i, j)下一列应该到的行.
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn = 10 + 1;
const int inf = 1000000;
int G[maxn][100 + 5];
int nex[maxn][100 + 5];
int dp[maxn][100 + 5];
int main()
{
int m, n;
while(scanf("%d%d", &m, &n) == 2)
{
int ans = inf, first = 0;
memset(nex, 0, sizeof(nex));
for(int i = 0; i < m; i++)
for(int j = 0; j < n; j++)
scanf("%d", &G[i][j]);
for(int i = n - 1; i >= 0; i--)//注意因为没一次走变动的地方列是固定的,而行则不,需要考虑如何dp
for(int j = 0; j < m; j++)
{
if(i == n - 1) dp[j][i] = G[j][i];
else
{
int go[] = {j - 1, j, j + 1};
for(int k = 0; k < 3; k++)
{
if(go[k] == -1) go[k] = m - 1;
if(go[k] == m) go[k] = 0;
}
sort(go, go + 3);
dp[j][i] = inf;
for(int k = 0; k < 3; k++)
{
int v = dp[go[k]][i + 1] + G[j][i];
if(v < dp[j][i])
{
dp[j][i] = v;
nex[j][i] = go[k];
}
}
}
if(i == 0 && dp[j][i] < ans) {ans = dp[j][i]; first = j;}
}
printf("%d", first + 1);
for(int i = nex[first][0], j = 1; j < n; i = nex[i][j], j++)
{
printf(" %d", i + 1);
}
printf("\n%d\n", ans);
}
return 0;
}