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;
}
View Code

猜你喜欢

转载自www.cnblogs.com/sanshi-2018/p/10474624.html