UVa 116 Unidirectional TSP (DP)
该题是《算法竞赛入门经典(第二版)》的一道例题,难度不算大。我先在没看题解的情况下自己做了一遍,虽然最终通过了,思路与书上的也一样。但比书上的代码复杂了很多,可见自己对问题的处理还是有所欠缺。
该题类似于数字三角形问题,处理的方式就是从倒数第二列逐步推到第一列, 每次选择其后一列权值最小的那条路径。最终找到花费最小的那个即可。由于出现多个答案时要输出字典序考前的路径,所以在选择路径的时候如果出现相同,要选择行数小的那个。我在处理这个问题时用了很多条件语句,使得最终的代码很长。下面是我的代码:
#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)的更多相关文章
- UVA 116 Unidirectional TSP(dp + 数塔问题)
Unidirectional TSP Background Problems that require minimum paths through some domain appear in ma ...
- UVA 116 Unidirectional TSP(DP最短路字典序)
Description Unidirectional TSP Background Problems that require minimum paths through some domai ...
- uva 116 Unidirectional TSP (DP)
uva 116 Unidirectional TSP Background Problems that require minimum paths through some domain appear ...
- uva 116 Unidirectional TSP【号码塔+打印路径】
主题: uva 116 Unidirectional TSP 意甲冠军:给定一个矩阵,当前格儿童值三个方向回格最小值和当前的和,就第一列的最小值并打印路径(同样则去字典序最小的). 分析:刚開始想错了 ...
- UVA 116 Unidirectional TSP 经典dp题
题意:找最短路,知道三种行走方式,给出图,求出一条从左边到右边的最短路,且字典序最小. 用dp记忆化搜索的思想来考虑是思路很清晰的,但是困难在如何求出字典序最小的路. 因为左边到右边的字典序最小就必须 ...
- UVA - 116 Unidirectional TSP 多段图的最短路 dp
题意 略 分析 因为字典序最小,所以从后面的列递推,每次对上一列的三个方向的行排序就能确保,数字之和最小DP就完事了 代码 因为有个地方数组名next和里面本身的某个东西冲突了,所以编译错了,后来改成 ...
- UVa - 116 - Unidirectional TSP
Background Problems that require minimum paths through some domain appear in many different areas of ...
- uva 116 - Unidirectional TSP (动态规划)
第一次做动规题目,下面均为个人理解以及个人方法,状态转移方程以及状态的定义也是依据个人理解.请过路大神不吝赐教. 状态:每一列的每个数[ i ][ j ]都是一个状态: 然后定义状态[ i ][ j ...
- UVA - 116 Unidirectional TSP (单向TSP)(dp---多段图的最短路)
题意:给一个m行n列(m<=10, n<=100)的整数矩阵,从第一列任何一个位置出发每次往右,右上或右下走一格,最终到达最后一列.要求经过的整数之和最小.第一行的上一行是最后一行,最后一 ...
随机推荐
- win10系统 Visual Studio 2013 Color Theme Editor插件 安装出错
下载这个版本,用vs2013打开安装即可:http://pan.baidu.com/s/1hrcfY1A
- 初识Devexpress ChartControl 之 动态添加stepline及TextAnnotation
最近在用devexpress 第三方软件做项目. devexpress 的控件使用简单.功能强大.类型丰富.界面优美.扩展性强.今天主要是动态生成了一条StepLine.生成后的效果(能力不强,所以做 ...
- asp.net BulletedList样式修改 css
首先编写一段简单的css脚本 然后呢,在asp:BulletedList中通过 CssClass ="style1"将样式作用到控件上.看看运行效果 注意到上下边框的颜色分别是红色 ...
- Login failed for user 'NT AUTHORITY\NETWORK SERVICE'的解决方法
1.打开SQL Server Manegement Studio 2.在 Security - logins 中 NETWORK SERVICE 3.双击该用户 Server Roles 中 勾选 ...
- Linux 常用命令学习
sed 大法: cat file | sed 's/string/replace_str/' file 按大小分割文件 split -b 100m filename 设置vi不自动转换tab: set ...
- C# 知识点记录(持续更新中)
从看C#入门经典开始系统的学习C#,本文主要记录学习过程中的一些知识点,也是我博客生涯的开始,比较重要成体系的部分会单重新写文章整理归纳. 1.一字不变的字符串 @字符 使转义序列不被处理,按照原样输 ...
- spring与hibernate整合事务管理的理解
在谈Spring事务管理之前我们想一下在我们不用Spring的时候,在Hibernate中我们是怎么进行数据操作的.在Hibernate中我们每次进行一个操作的的时候我们都是要先开启事务,然后进行数据 ...
- QF——网络之网络请求的几种方式,图片缓存
同步请求和异步请求: 同步请求会阻塞主线程:不会开启新的线程,还是主线程,所以直到请求成功后,才能执行其它操作. 异步请求不会阻塞主线程.开启新的线程去请求服务器,而不影响用户的交互操作等其他动作. ...
- mysql建立数据库的方法
mysql建立数据库的方法 方法一:使用create mysql> create database roudy; Query OK, 1 row affected (0.00 sec) mysq ...
- Python进阶之函数式编程(把函数作为参数)
什么是函数式编程? 什么是函数式编程? 函数:function 函数式:functional,一种编程范式 函数式编程是一种抽象计算的编程模式 函数≠函数式,比如:计算≠计算机 在计算机当中,计算机硬 ...