如果上交复试的题的难度都是这个水平,那么就好说了,但这个题确实简单了点
重点在如何打印字典序的地方
//这题应该还算比较的容易的 //思路还是先定义状态,d[i][j]代表当前点的距离最后一列的的路径的最小整数和 //状态转移方程就是d[i][j] + A[i][j] + min(右上右下右) //如果要输出字典序,那么就还需要一个next矩阵,来记录每一个状态的下一步往哪里走 //当然也可以不用记录,但是需要递归的去一个一个的计算 #include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxr = 15; const int maxc = 110; int row,col; int G[maxr][maxc]; int vis[maxr][maxc]; int d[maxr][maxc]; int Next[maxr][maxc]; bool read_G() { memset(vis,0,sizeof(vis)); if(scanf("%d%d",&row,&col) != 2) return false; for(int i = 0;i < row;i++) { for(int j = 0;j < col;j++) { scanf("%d",&G[i][j]); } } return true; } int dp(int r,int c) { if(vis[r][c]) { return d[r][c]; } vis[r][c] = 1; if(c == col - 1) { d[r][c] = G[r][c]; return d[r][c]; } int ans[3]; for(int i = -1;i <= 1;i++) { ans[i + 1] = dp((r + i + row )% row,c + 1); } sort(ans,ans + 3); if(ans[0] == ans[1])//有相同的 { if(r == 0) { if(d[r][c + 1] == ans[0]) Next[r][c] = r; else Next[r][c] = r + 1; } else if(r == row - 1) { if(d[0][c + 1] == ans[0]) Next[r][c] = 0; else Next[r][c] = r - 1; } else { if(d[r - 1][c + 1] == ans[0]) Next[r][c] = r - 1; else Next[r][c] = r ; } } else { for(int i = -1;i <= 1;i++) { if(ans[0] == d[(r + i + row )% row][c + 1]) { Next[r][c] = (r + i + row )% row; break; } } } d[r][c] = min(ans[0],min(ans[1],ans[2])) + G[r][c]; return d[r][c]; } int main() { #ifdef local freopen("input.txt","r",stdin); #endif while(read_G()) { int Ans = 0; for(int i = 0;i < row;i++) { dp(i,0); if(d[i][0] < d[Ans][0]) Ans = i; } int ans = Ans; for(int c = 0;c < col ;c++) { if(c) printf(" "); printf("%d",ans + 1); ans = Next[ans][c]; } printf("\n%d\n",d[Ans][0]); } return 0; }