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

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

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 ;
}

最新文章

  1. 移动web开发介绍——浏览器
  2. Centos5.8 安装 PHP5.5 和 memcached
  3. 使用github和hexo搭建博客
  4. hiberante入门
  5. Codeforces Round #336 (Div. 2)A. Saitama Destroys Hotel 水题
  6. Deep Residual Learning for Image Recognition(MSRA-深度残差学习)
  7. JSP指令 include 和forward
  8. css图片上下垂直居中
  9. VK Cup 2012 Qualification Round 1---C. Cd and pwd commands
  10. hdu 5314 动态树
  11. 【ASP】response和sever对象实现用户登录
  12. 利用phpredis实现PHP操作Redis
  13. HDU 1003 Max Sum 求区间最大值 (尺取法)
  14. BZOJ2319 : 黑白棋游戏
  15. rabbitmq management advance lesson
  16. [转]IIS 日志记录时间和实际时间 不一样
  17. NODE中解决跨域请求的问题
  18. Code alignment 代码对齐改进(VS2017)
  19. Rocket Typist for Mac(增强型文本快速输入工具)破解版安装
  20. 转:jdk动态代理实现

热门文章

  1. onload函数不执行
  2. MySQL的数据类型(一)
  3. 【原创】从 列表的重复 到 用sum展开二层嵌套列表将子元素合并
  4. C调用约定__cdecl、__stdcall、__fastcall、__pascal分析
  5. 【poe设备加电配置】
  6. git的初始配置(简易的命令行)
  7. [转]ThinkPHP5 隐藏index.php问题
  8. flask过滤器
  9. python七类之字符串
  10. 《史上最简单的MySQL教程》系列分享专栏