UVa 116 Unidirectional TSP(일반 여행사 DP)

6226 단어 uva
제목:
대가가 가장 적은 경로를 구하다.
아이디어:
경로가 필요하고 사전의 순서가 가장 작은 서열을 출력해야 하기 때문이다.그래서 DP를 역으로 구하고 dfs를 모방하면 문제 풀이의 난이도를 낮출 수 있다.
#include <cstdio>

#include <cstdlib>

#include <cstring>



#define min(a,b) (((a) < (b)) ? (a) : (b))



int map[15][105];

int dp[15][105], path[15][105];

int n, m;



int main()

{

    while (scanf("%d %d", &n, &m) != EOF)

    {

        for (int i = 0; i < n; ++i)

            for (int j = 0; j < m; ++j)

                scanf("%d", &map[i][j]);



        memset(dp, 0, sizeof(dp));

        memset(path, 0,sizeof(path));



        for (int j = m - 1; j >= 0; --j)

        {

            for (int i = 0; i < n; ++i)

            {

                int a = dp[(i-1+n)%n][j+1];

                int b = dp[i][j+1];

                int c = dp[(i+1)%n][j+1];

                int mm;

                if (a > b)

                    mm = min(b, c);

                else

                    mm = min(a, c);



                dp[i][j] = map[i][j] + mm;

                

                path[i][j] = 1e9;



                if (mm == a)

                    path[i][j] = (i - 1 + n) % n;



                if (mm == b)

                    path[i][j] = min(path[i][j], i);



                if (mm == c)

                    path[i][j] = min(path[i][j], (i + 1) % n);

            }

        }

        int ans = 1e9;

        int id;

        for (int i = 0; i < n; ++i)

            if (ans > dp[i][0])

                ans = dp[i][0], id = i;



        printf("%d", id + 1);

        id = path[id][0];



        for (int j = 1; j < m; ++j)

        {

            printf(" %d", id + 1);

            id = path[id][j];

        }



        printf("
%d
", ans); } return 0; }

좋은 웹페이지 즐겨찾기