UVA116

来源:互联网 发布:卖家怎么开淘宝客 编辑:程序博客网 时间:2024/06/05 14:56

题目链接:https://vjudge.net/problem/UVA-116

          一个格子可以往它上一行的后一个格子,本行的后一个格子和下一行的后一个格子走,找出花费最少的路径,输出路径上每列的行号,            多解输出字典序最小。

思路:

         多阶段决策问题,状态的定义不难看出:d[i][j]:从(i,j)出发到最后一列的最短距离。

         关键是如何输出“字典序”最小的路径:只需要在求d[i][j](最优)的时候记录下由那个转移过来的,顺序还是逆序枚举列都可以,顺序枚          举只是多了一个逆序输出的过程。

#include<iostream>#include<algorithm>#include<string>#include<cmath>#include<vector>#include<set>#include<map>#include<stack>#include<queue>#include<cstdio>#include<cstring>#define ll long long#define pq priority_queueusing namespace std;const int maxn = 1e5 + 10;int n,m;int a[105][105], dp[105][105], nextt[105][105], rows[105];int main(){    while(scanf("%d%d", &n, &m)!=EOF)    {        int maxx = 0x3f3f3f3f;        int first;        for(int i = 1; i <= n; i++)        {            for(int j = 1; j <= m; j++)            {                scanf("%d", &a[i][j]);                if(j == m)                    dp[i][j] = a[i][j];                else                    dp[i][j] = 0x3f3f3f3f;            }        }        for(int i = m-1; i >= 1; i--) //列        {            for(int j = 1; j <= n; j++)            {                int row[3] = {j-1, j, j+1};                if(j == 1)                    row[0] = n;                if(j == n)                    row[2] = 1;                sort(row, row+3);                for(int k = 0; k < 3; k++)                {                    int ans = dp[row[k]][i+1] + a[j][i];                    if(ans < dp[j][i])                    {                        dp[j][i] = ans;                        nextt[j][i] = row[k];                    }                }                if(i == 1 && dp[j][i] < maxx)                {                    first = j;                    maxx = dp[j][i];                }            }        }        if(m==1)        {            for(int i = 1; i <= n;i++)            {                if(maxx > a[i][1])                {                    maxx = a[i][1];                    first = i;                }            }        }        printf("%d",first);        for(int i = nextt[first][1], j = 2; j <= m; i = nextt[i][j],j++)            printf(" %d", i);        printf("\n%d\n", maxx);    }    return 0;}