(UVA - 116)Unidirectional TSP(DP,多段图的最短路问题)

27 篇文章 0 订阅
27 篇文章 0 订阅

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

题意:给定m行n列(m<=10,n<=100)的整数矩阵,从第一列的任何一个位置出发每次往右或右上或右下走一格,最终到达最后一列。要求经过的整数之和最小。整个矩阵是环形的,即 第一行的上一行是最后一行,最后一行 的下一行是第一行。输出路径上的每列的行号。多解时输出字典序最小的。

分析:题目是紫书上的,P270. LRJ大神把这个分在 多阶段决策中的多段图的最短路问题中。
因为在本题中,每个阶段就是每一列,每个阶段都有三种决策:直行,右上,右下。

下面是我的理解,在本题中,因为终态是 最后一列,初态是 第一列。
DP做法,n,m的范围不大,设dp[i][j]: 从格子(i,j)出发到 最后一列的 最小整数和。 这种假设方法可以理解为最后一列为初态, 那么循环采用逆推的方法枚举列。

/* 若把dp[i][j] 设为: 从 第一列出发 到 最后一列的最小整数和,那么就顺推 枚举*/

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=105;
const int INF=0x3f3f3f3f;
int a[N][N],dp[N][N];
int n,m,ne[N][N];
void solve()
{
    int first=0;
    for(int j=n-1; j>=0; j--)///逆推  枚举列
    {
        for(int i=0; i<m; i++)///枚举行
        {
            if(j==n-1) dp[i][j]=a[i][j];///边界: 到达最后一列
            else
            {
                dp[i][j]=INF;///初始时  是一个不可能达到的值
                int rows[]= {i,i-1,i+1};///三种决策
                if(i==0) rows[1]=m-1;/// 第1行上面是最后一行
                if(i==m-1) rows[2]=0;/// 最后一行下面是第一行,  符合题中 矩阵是环的规则
                sort(rows,rows+3); ///对rows 重新排序,找到字典序最小
                for(int k=0; k<3; k++)///通过对三种决策的试探,找到最小的那一个
                {
                    int val=a[i][j]+dp[rows[k]][j+1];
                    if(dp[i][j]>val)///当前状态比下一个状态的 整数和要大
                    {
                        dp[i][j]=val;
                        ne[i][j]=rows[k];
                    }
                }
            }
            if(j==0&&dp[i][j]<dp[first][j])///第一列
                first=i;///first记录第一列的行号
        }
    }
    printf("%d",first+1);
    int j=1;
    for(int i=ne[first][0]; j<n; i=ne[i][j],j++)
    ///ne记录行号,此处实现类似链表,因为循环中rows的处理,此处的输出一定是字典序最小(最小整数和相等的情况下)
        printf(" %d",i+1);
    printf("\n%d\n",dp[first][0]);////dp[first][0]就是题目要求的最小整数和
}
int main()
{
    while(~scanf("%d%d",&m,&n))
    {
        for(int i=0; i<m; i++)
            for(int j=0; j<n; j++)
                scanf("%d",&a[i][j]);
        solve();
    }
    return 0;
}

题目读起来 很长,感觉啰嗦,有点迷糊,但是抓住题目的关键点: 起始在第一列的任意位置,矩阵是环形的,终态在最后一列,要求最小整数和, 那么是最短路问题,结合数据范围,可以采用DP,要求输出行号(字典序顺序)。用数组记录行号 感觉还是有迹可循,但是这还是清楚了之火才这样觉得。。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值