UVa 116 - Unidirectional TSP

来源:互联网 发布:淘宝网商城女装韩版30 编辑:程序博客网 时间:2024/06/06 00:37

题目:给你一个n*m的数字表格,找到一条从左到右的路径,使得上面的数字和最小。

           (每次可以从(i,j),走到(i,j+1),(i+1,j),(i-1,j)可以越界。)

分析:因为要字典序最小,所以采用从右向左的方式dp;

           状态:f(i,j)表示走到(i,j)的最小和,则有转移方程:

           f(i,j)= min(f(i+1,j+1),f(i,j+1),f(i-1,j+1));

           记录路径输出即可。

/*********************************************** * Author: fisty * Created Time: 2015/2/4 16:58:26 * File Name   : uva116.cpp *********************************************** */#include <iostream>#include <cstring>#include <deque>#include <cmath>#include <queue>#include <stack>#include <list>#include <map>#include <set>#include <string>#include <vector>#include <cstdio>#include <bitset>#include <algorithm>using namespace std;#define Debug(x) cout << #x << " " << x <<endl#define Memset(x, a) memset(x, a, sizeof(x))const int INF = 0x3f3f3f3f;typedef long long LL;typedef pair<int, int> P;#define FOR(i, a, b) for(int i = a;i < b; i++)#define MAX_N  1000int m, n;int a[MAX_N][MAX_N];int d[MAX_N][MAX_N];int next[MAX_N][MAX_N];int main() {    //freopen("in.txt", "r", stdin);    cin.tie(0);    ios::sync_with_stdio(false);    while(cin >> m >> n){        FOR(i, 0, m){            FOR(j, 0, n){                cin >> a[i][j];            }        }        int ans = INF, first = 0;        for(int j = n-1; j >= 0; j--){            for(int i = 0;i < m; i++){                if(j == n-1) d[i][j] = a[i][j];                else {                    int row[3] = {i, i-1, i+1};      //下一步往右,右上,右下走                    if(i == 0) row[1] = m-1;       //第0行上面是m-1行                    if(i == m-1) row[2] = 0;       //第m-1行下面是第0行                    sort(row, row + 3);                    d[i][j] = INF;                    for(int k = 0;k < 3; k++){                        int v = d[row[k]][j+1] + a[i][j];                        if(v < d[i][j]){                            d[i][j] = v;                            next[i][j] = row[k];                        }                    }                }                if(j == 0 && d[i][j] < ans){                    ans = d[i][j];                    first = i;       //下标从0开始                }            }        }        cout << first + 1;        for(int i = next[first][0], j = 1;j < n; i = next[i][j], j++){            cout << " " << i + 1;        }        cout << endl << ans << endl;    }    return 0;   }


0 0
原创粉丝点击