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)的整数矩阵,从第一列任何一个位置出发每次往右,右上或右下走一格,最终到达最后一列.要求经过的整数之和最小.第一行的上一行是最后一行,最后一 ...
随机推荐
- 递归与arguments.callee;
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- javascript第十一课,string对象
length: //字符串长度,索引从0开始 var str='说东方闪电方式的'; alert(str.length); charAt(index); var n='阿斯顿发生打算'; n.cha ...
- kubernetes之kube-ApiServer代码分析
一.概述: kube-ApiServer相当于是k8集群的一个入口,不论通过kubectl还是使用remote api 直接控制,都要经过apiserver.apiserver说白了就是一个serve ...
- CSS的W3C标准的盒子模型和低版本IE浏览器的盒子模型
CSS中盒子模型的组成由内容区(content).内边距(padding).边框(border).外边距(margin)组成.内边距可细分为 padding-top.padding-right.pad ...
- 获取ini文件所有的Sections和Keys
获取ini文件中所有的Sections和Keys,并以pair对的方式存入到vector中 #include <iostream> #include <windows.h> # ...
- hadoop笔记之MapReduce的应用案例(利用MapReduce进行排序)
MapReduce的应用案例(利用MapReduce进行排序) MapReduce的应用案例(利用MapReduce进行排序) 思路: Reduce之后直接进行结果合并 具体样例: 程序名:Sort. ...
- Android 动画系列
Android种最常用的动画: ~1~Tween动画,就是对场景里的对象不断的进行图像变化来产生动画效果(旋转.平移.放缩和渐变) Tweene Animations 主要类: Animation ...
- CSS 技术关键字
CSS 技术关键字 元素 替换元素 非替换元素------替换元素和非替换元素的分类是CSS范畴内的,其它的分类都不属于CSS定义的 替换元素和非替换元素的定义是出于“我 ...
- poj 1141 Brackets Sequence(区间DP)
题目:http://poj.org/problem?id=1141 转载:http://blog.csdn.net/lijiecsu/article/details/7589877 定义合法的括号序列 ...
- Orchard 源码探索(Module,Theme,Core扩展加载概述)
参考: http://www.orchardch.com/Blog/20120830071458 1. host.Initialize(); private static IOrchardHost H ...