这道题目并不是很难理解,题目大意就是求从第一列到最后一列的一个字典序最小的最短路,要求不仅输出最短路长度,还要输出字典序最小的路径。

这道题可以利用动态规划求解。状态定义为:

cost[i][j] = max{cost[i+1][j+k]+c[i][j]}(k=-1,0,1)

关于最短路长度的求法,我们可以通过上边的状态转移方程递推求解。cost代表从第i列到第c-1列的最短路,只要找出cost[0][j](j代表行号)中的最大值,我们得到的结果就是最短路。

我们已经得到了最短路的长度。下一步,我们应该如何输出完整的最短路路径。题目说了最短路可能有多个,并且要求输出字典序最小的最短路。

如何得到字典序最小的最短路?

要让字典序最小,那么我们的路径从最左列到最右列,每一列的行号应该尽可能的小。根据我们目前已知的条件,我们可以在第一列中找出属于最短路的最小行号(对应代码行31-34行)。至此我们得到正确路径的开端。然后我们需要去找这条路径上的对应下一列的行号。在这里我们就需要另外一个二维数组nexts(记录当前路径的下一个行号的最小值)。

如何确保是最小值?我们寻找当前状态时是按顺序寻找当前状态的最小值的,因此得到的第一个状态的最小值所对应的行号一定是我们所需要的最小行号。这里特别要注意最后一行的下一行是第一行 这个条件,我起初是按照以下方式去执行三种决策(直行,右上,右下):

                 for(int k = -;k<=;k++){
if(cost[(j+k+r)%r][i+] <t){
nexts[j][i] = (j+k+r)%r;
t = cost[(j+k+r)%r][i+];
}
}

在一般情况下,这处代码不会有问题。可是一旦最短路从跨越了边界,那么行的访问顺序就变得无序了(如r-1,0,1),因此需要一次排序。

完整代码如下:

 #include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <climits>
using namespace std;
int cost[][];
int C[][];
int nexts[][];
int main(){
int r,c;
while(~scanf("%d%d",&r,&c)){
for(int i = ; i < r; i++)
for(int j = ; j < c; j++)
scanf("%d",&C[i][j]);
for(int i = ;i<r;i++)cost[i][c] = ;
int first= ,ans = INT_MAX;
for(int i = c-;i >= ;i--){
for(int j = ; j < r; j++){
int t = INT_MAX;
int ks[] ={-,,};
ks[]=(j-+r)%r,ks[]=(j+r)%r,ks[]=(j++r)%r;
sort(ks,ks+);
for(int k = ;k<=;k++){
if(cost[ks[k]][i+] < t){
nexts[j][i] = ks[k];
t = cost[ks[k]][i+];
}
}
cost[j][i] = t + C[j][i] ;
if(i== && cost[j][i] < ans){
ans = cost[j][i];
first = j;
}
} }
int minn = INT_MAX;
cout << first + ;
for(int j = nexts[first][],i=; i < c;j=nexts[j][i],i++){
cout <<" "<< j + ;
}
for(int i = ;i<r;i++){
minn = min(minn,cost[i][]);
}
cout <<endl<< minn << endl;
}
return ;
}

uva 116 Unidirectional TSP(动态规划,多段图上的最短路)的更多相关文章

  1. UVa 116 单向TSP(多段图最短路)

    https://cn.vjudge.net/problem/UVA-116 题意:给出m行n列的整数矩阵,从第一列任何一个位置出发每次往右,右上或右下走一格,最终到达最后一列,要求经过的整数之和最小. ...

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

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

  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 + 数塔问题)

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

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

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

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

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

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

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

  9. UVa - 116 - Unidirectional TSP

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

随机推荐

  1. 为什么有IP还需要硬件地址,或者说为什么有硬件地址还需要IP

    只用MAC 虽然每个设备都有唯一的硬件地址,但不都是MAC格式. 只用MAC的话理论上是可行的,但是其中 兼容不同的硬件地址,处理起来是非常困难的.而且数据链路层也没有必要处理网络层的逻辑. 只用IP ...

  2. iOS 让视图UIView单独显示某一侧的边框线

    iOS 让视图UIView 单独显示某一侧的边框线   有时候需要让view显示某一侧的边框线,这时设置layer的border是达不到效果的.在网上查阅资料发现有一个投机取巧的办法,原理是给view ...

  3. Java分享笔记:RandomAccessFile流 & 在文件指定位置插入内容

    RandomAccessFile流:随机存取文件流,该类定义了一个记录指针,通过移动指针可以访问文件的任意位置,且对文件既可以读也可以写.使用该类的write方法对文件写入时,实际上是一种覆盖效果,即 ...

  4. Linux计算某一列的和

    ll | awk '{print $5}' | egrep -v "^$"| paste -sd+|bc 简单说明: ll:拿到当前目录下所有的文件大小 awk:拿到第几列 egr ...

  5. 免安装版Tomcat9中间件的安装

    [环境准备] OS版本:Windows10.64位 Tomcat版本:apache_tomcat9.0.7.zip免安装版 [彻底卸载已安装的Tomcat中间件] 01:由于是免安装版本,因此直接删除 ...

  6. MySQL备份恢复之mysqldump

      Preface       The day before yesterday,there's a motif about the lock procedure when backing up My ...

  7. struts2的token interceptor

    关于struts2的token拦截器的说明 原理:struts2的token interceptor是关于重复提交的拦截器,其实现是:在form表单中加入token标签,如下: <form ac ...

  8. android Service服务(二)

    1.1 活动和服务进行通信 上一节中我们学习了启动和停止服务的方法.不知道你又没有发现,虽然服务是在活动里启动的,但在启动了服务之后,活动和服务基本上就没关系了,确实如此,我们在活动里调用了start ...

  9. Yaf学习(三)----Yaf类库Library和Model的命名规则

    1.Yaf的library和model的文件命名规则和调用 1.1在项目中,往往需要封装一些,如redis,不同的产品需要用不同的库等等等,这就涉及到封装 1.在 Yaf 中,我们可以写一个单例模式的 ...

  10. 终于搞定了cxgrid的多行表头(转终于搞定了cxgrid的多行表头 )

    终于搞定了cxgrid的多行表头 转自:http://mycreature.blog.163.com/blog/static/556317200772524226400/     这一周都在处理dbg ...