UVA - 116 Unidirectional TSP (动态规划)
收获如下:
1. 如果用递归求解(当然不会去用非记忆化搜索, 否则太耗时,复杂度将降到和用回溯法求解一样是指数级的了)
则务必注意d数组的初值问题:1. 起点位置直接用所给数据赋值。2. 其他点赋合适的特殊值,以作标记数组,若不方便,可以考虑另开辟vis进行标记。
2. 如果用递推求解。
3. 打印中间路径需要注意的问题。
#include<bits/stdc++.h> using namespace std; const int maxm = 10 + 3; const int maxn = 100 + 3; int m, n; int buf[maxm][maxn]; int path[maxm][maxn]; int d[maxm][maxn]; int solve(int i, int j) { if(d[i][j] != INT_MIN) return d[i][j]; else{ int ans = INT_MAX, ans_i = INT_MAX; for(int k = -1; k < 2; k++){ int ii = (i + k + m) % m; int& t = d[ii][j+1]; //if(t == 0) if(t == INT_MIN) t = solve(ii, j + 1); if(buf[i][j] + t < ans){ ans_i = ii; ans = buf[i][j] + t; } } for(int k = -1; k < 2; k++){ int ii = (i + k + m) % m; int& t = d[ii][j+1]; if(t + buf[i][j] == ans && ii < ans_i){ ans_i = ii; } } path[i][j+1] = ans_i; return ans; } } int main() { // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); while(cin >> m >> n){ for(int i = 0; i < m; i++){ for(int j = 0; j < n; j++){ cin >> buf[i][j]; } } int ans = INT_MAX, ans_i; for(int i = 0; i < m; i++){ for(int i = 0; i < m; i++){ for(int j = 0; j < n; j++) d[i][j]= INT_MIN; } for(int i = 0; i < m; i++) d[i][n-1] = buf[i][n-1]; if(ans > solve(i, 0)){ ans = solve(i, 0); ans_i = i; } } for(int i = ans_i, j = 0; j < n; j++, i = path[i][j]){ if(j == 0) cout << i + 1; else cout << ' ' << i + 1; } cout << endl << ans << endl; } return 0; }