该题是《算法竞赛入门经典(第二版)》的一道例题,难度不算大。我先在没看题解的情况下自己做了一遍,虽然最终通过了,思路与书上的也一样。但比书上的代码复杂了很多,可见自己对问题的处理还是有所欠缺。

  该题类似于数字三角形问题,处理的方式就是从倒数第二列逐步推到第一列, 每次选择其后一列权值最小的那条路径。最终找到花费最小的那个即可。由于出现多个答案时要输出字典序考前的路径,所以在选择路径的时候如果出现相同,要选择行数小的那个。我在处理这个问题时用了很多条件语句,使得最终的代码很长。下面是我的代码:

  

 #include <iostream>
#include <cstdio>
#include <cstring> using namespace std; long long a[][];
int pre[][]; int main()
{
int m, n, i, j, temw, temr; while(scanf("%d%d", &m, &n) == )
{
for(i = ; i <= m; i++)
{
for(j = ; j <= n; j++)
{
scanf("%lld", &a[i][j]);
}
}
for(j = n-; j >= ; j--)
{
for(i = ; i <= m; i++)
{
//首先考虑向上方向的路径
if(i == ) //第一行,向上方向走到最后一行
{
temw = a[m][j + ];
temr = m;
}
else
{
temw = a[i - ][j + ];
temr = i - ;
}
//考虑向正前方向的路径
if(a[i][j + ] < temw)
{
temw = a[i][j + ];
temr = i;
}
else if(a[i][j + ] == temw)
{
temr = min(temr, i); //相等取行号小的。
}
//考虑向下方向的路径
if(i == m) //最后一行,向下走到第一行
{
if(a[][j + ] < temw)
{
temw = a[][j + ];
temr = ;
}
else if(a[][j + ] == temw)
{
temr = min(temr, );
}
}
else
{
if(a[i + ][j + ] < temw)
{
temw = a[i + ][j + ];
temr = i + ;
}
else if(a[i + ][j + ] == temw)
{
temr = min(temr, i + );
}
}
a[i][j] += temw;
pre[i][j] = temr; //记录路径
}
}
temw = a[][];
temr = ;
for(i = ; i <= m; i++) //寻找最小的。
{
if(a[i][] < temw)
{
temw = a[i][];
temr = i;
}
}
//输出路径
if(n == )
{
printf("%d\n", temr);
}
else
{
for(i = temr, j = ; j <= n-;)
{
printf("%d ", i);
i = pre[i][j];
j++;
}
printf("%d\n", i);
}
printf("%lld\n", a[temr][]);
}
return ;
}

  显然,在处理三个方向时,用了很多代码,而书上是这样做的:

  

 int rows[] = {i, i-, i+};    //普通情况下的行号
if(i == ) //书上第一行行号为0,如果是第一行,向上的行号需要改变。
rows[] = m - ; //最后一列列号为m-1
if(i == m-)
rows[] = ;
d[i][j] = INF; //数组d用来存储权值
sort(rows, rows+); //先排序,再比较
for(int k = ; k < ; k++)
{
int v = d[rows[k]][j+] + a[i][j];
if(v < d[i][j])
{
d[i][j] = v;
next[i][j] = rows[k];
}
}

  显然,书上通过先排序再比较,这样从最小的行号开始,找最小权值,找到的最小权值一定是行号最小的,减小了很多代码量。

  还需要说的一点是,这道题我一开始看错了题意!!!这是比赛的大忌! 根据所给的图,想当然地以为是从第一行第一列开始走到最后一行最后一列。顺便说一下这种情况的我的思路吧。这种情况下,需要一个bool型数组标记每个点是否可到达,首先标记终点可到达,然后从倒数第二列循环,选择后一列中可以到达且权值最小,行号最小的一条路径,并标记该点可到达,如果后面没有可到达的点,就标记该点不可到达。循环到第一列时,只需要考虑起点即可。其他类似于原题。

UVa 116 Unidirectional TSP (DP)的更多相关文章

  1. UVA 116 Unidirectional TSP(dp + 数塔问题)

     Unidirectional TSP  Background Problems that require minimum paths through some domain appear in ma ...

  2. UVA 116 Unidirectional TSP(DP最短路字典序)

    Description    Unidirectional TSP  Background Problems that require minimum paths through some domai ...

  3. uva 116 Unidirectional TSP (DP)

    uva 116 Unidirectional TSP Background Problems that require minimum paths through some domain appear ...

  4. uva 116 Unidirectional TSP【号码塔+打印路径】

    主题: uva 116 Unidirectional TSP 意甲冠军:给定一个矩阵,当前格儿童值三个方向回格最小值和当前的和,就第一列的最小值并打印路径(同样则去字典序最小的). 分析:刚開始想错了 ...

  5. UVA 116 Unidirectional TSP 经典dp题

    题意:找最短路,知道三种行走方式,给出图,求出一条从左边到右边的最短路,且字典序最小. 用dp记忆化搜索的思想来考虑是思路很清晰的,但是困难在如何求出字典序最小的路. 因为左边到右边的字典序最小就必须 ...

  6. UVA - 116 Unidirectional TSP 多段图的最短路 dp

    题意 略 分析 因为字典序最小,所以从后面的列递推,每次对上一列的三个方向的行排序就能确保,数字之和最小DP就完事了 代码 因为有个地方数组名next和里面本身的某个东西冲突了,所以编译错了,后来改成 ...

  7. UVa - 116 - Unidirectional TSP

    Background Problems that require minimum paths through some domain appear in many different areas of ...

  8. uva 116 - Unidirectional TSP (动态规划)

    第一次做动规题目,下面均为个人理解以及个人方法,状态转移方程以及状态的定义也是依据个人理解.请过路大神不吝赐教. 状态:每一列的每个数[ i ][ j ]都是一个状态: 然后定义状态[ i ][ j ...

  9. UVA - 116 Unidirectional TSP (单向TSP)(dp---多段图的最短路)

    题意:给一个m行n列(m<=10, n<=100)的整数矩阵,从第一列任何一个位置出发每次往右,右上或右下走一格,最终到达最后一列.要求经过的整数之和最小.第一行的上一行是最后一行,最后一 ...

随机推荐

  1. Advanced Fruits(好题,LCS的模拟)

    Advanced Fruits Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)T ...

  2. Android平台音频信号FFT的实现

    转载请标明出处:http://blog.csdn.net/sctu_vroy/article/details/45871823 功能:加载本地SD卡中moveDsp文件夹中的音频文件(包括录音获取文件 ...

  3. self

    self在对象方法中使用,指代调用当前对象方法的对象.可以利用self->属性名称的方法访问成员变量 self在类方法中使用,其指代的是当前类. 使用总结: self 谁调用当前方法,self就 ...

  4. 第四课 Grid Control实验 GC Agent安装(第一台机器部署) 及卸载

    3.GC Agent安装(第一台机器部署) 安装Agent 拷贝agent,现在ocm2机器上查找agent.linux  查找文件的方法: find ./ -name agent*linux 把ag ...

  5. perl 递归地遍历目录下的文件

    #!/usr/bin/perl -w use strict; use File::Spec; local $\ ="\n";#当前模块的每行输出加入换行符 my %options; ...

  6. poco vs Boost[ZZ]

    http://wooce.iteye.com/blog/634395 POCO的优点: 1) 比boost更好的线程库,特别是一个活动的方法的实现,并且还可设置线程的优先级. 2) 比 boost:a ...

  7. zabbix中文配置及乱码问题

    1.切换成中文 2.发现有乱码出现 由于zabbix的web端没有中文字库,所以我们使用windows中的字体. 找到简体字的存储位置——copy到桌面或其他位置——上传到zabbix服务器——web ...

  8. AutoCompleteTextview、MultiAutoCompleteTextView

    AutoCompleteTextview     动态匹配输入内容文本框      属性:           android:completionThreshold="2";   ...

  9. Linux网络管理——网关作用

    1. 网络基础 .note-content {font-family: "Helvetica Neue",Arial,"Hiragino Sans GB",&q ...

  10. HTML DOM 属性记录

    将HTML DOM中几个容易常用的属性做下记录,需要的朋友可以参考下.     nodeName.nodeValue 以及 nodeType 包含有关于节点的信息. nodeName 属性含有某个节点 ...