一、题目

给一个m行n列(m <= 10,n <= 100)的整数矩阵,从第一列任何位置出发每次往右、右下、右上走一格,最终达到最后一列。要求经过的整数之和最小。整个矩阵是环形的,即第一行的上一行是最后一行,最后一行的下一行是第一行。输路径上每一列的行号及路径上的整数和,多解时输出字典序最小的。

二、解题思路

我们按列考虑,从最后一列开始,每一列可以由前一列决定,设dp[i][j]表示由格子(i,j)到最后一列的最小开销。于是有dp[i][j] = max(dp[i][j + 1],dp[i - 1][j + 1],dp[i +1][j + 1])。把最后一列初始化为其本身,从右至左可得到每一列的情况,取第一列中的最小即可。由于要输出路径,用nextpos[i][j]记录在j+1列时选取的行坐标。字典序的处理见代码注释。

三、代码实现

 #include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
using namespace std; const int INF = 0x3f3f3f3f;
const int maxm = + ;
const int maxn = + ;
int maze[maxm][maxn],dp[maxm][maxn]; //dp[i][j]表示从(i,j)出发到最后一列的最小值
int nextpos[maxn][maxn]; //nextpos[i][j]记录在j+1列时选取的行坐标
int m, n; void slove()
{
int ans = INF, first = ;
for (int j = n - ; j >= ; j--) //从右至左
{
for (int i = ; i < m; i++)
{
if (j == n - ) dp[i][j] = maze[i][j]; //边界
else
{
int rows[] = {i,i - ,i+};
if (i == ) rows[] = m - ; //注意考虑m = 1、2
if (i == m - ) rows[] = ;
sort(rows, rows + ); //保证字典序最小
dp[i][j] = INF;
for (int k = ; k < ; k++)
{
int tmp = dp[rows[k]][j + ] + maze[i][j];
if (tmp < dp[i][j])
{
dp[i][j] = tmp;
nextpos[i][j] = rows[k]; //dp更新,nextpos也会更新,这保证了nextpos记录的是最优路径
}
}
}
if (j == && dp[i][j] < ans)
{
ans = dp[i][j];
first = i;
}
}
} printf("%d", first + );
for (int i = nextpos[first][],j = ; j < n; j++)
{
printf(" %d", i + );
i = nextpos[i][j];
}
printf("\n%d\n", ans);
} int main()
{
while (scanf("%d%d",&m,&n) == )
{
for (int i = ; i < m; i++)
for (int j = ; j < n; j++)
scanf("%d", &maze[i][j]); slove();
}
return ;
}

动态规划初步-单向STP的更多相关文章

  1. 清北学堂—2020.1提高储备营—Day 4 afternoon(动态规划初步(一))

    qbxt Day 4 afternoon --2020.1.20 济南 主讲:顾霆枫 目录一览 1.动态规划初步 2.记忆化搜索 3.递推式动态规划 4.记忆话搜索与递推式动态规划的转化 5.状态转移 ...

  2. 动态规划初步--最长上升子序列(LIS)

    一.问题 有一个长为n的数列 a0,a1,a2...,an-1a.请求出这个序列中最长的上升子序列的长度和对应的子序列.上升子序列指的是对任意的i < j都满足ai < aj的子序列. 二 ...

  3. 什么是动态规划?动态规划的意义是什么?https://www.zhihu.com/question/23995189

    阮行止 上海洛谷网络科技有限公司 讲师 intro 很有意思的问题.以往见过许多教材,对动态规划(DP)的引入属于"奉天承运,皇帝诏曰"式:不给出一点引入,见面即拿出一大堆公式吓人 ...

  4. OI暑假集训游记

    莞中OI集训游记 Written BY Jum Leon. I        又是一载夏,本蒟蒻以特长生考入莞中,怀着忐忑的心情到了8月,是集训之际.怀着对算法学习的向往心情被大佬暴虐的一丝恐惧来到了 ...

  5. [bzoj\lydsy\大视野在线测评]题解(持续更新)

    目录: 一.DP 二.图论 1.最短路 2.强连通分量 三.利用单调性维护 四.贪心 五.数据结构 1.并查集 六.数学 1.计数问题 2.数学分析 七.博弈 八.搜索 /////////////// ...

  6. 帝都Day3——各种dp

    备注:Day1 Day2记得笔记太233,所以就不发了 备注2:Day4~Day7发不发看心情qaq (7.17持续更新中...) 动态规划A 记忆化搜索 & 动态规划初步 8点15: 杨姓d ...

  7. bzoj 1010 (单调决策优化)

    能够非常好的证明单调决策性质.用   记sum[i]=sigma(C[1],C[2].....C[k]);f[i]=sum[i]+i;  c=l-1; 有转移dp[i]=min( dp[j]+(f[i ...

  8. 1D1D动态规划优化初步

    再学习一下动态规划的基本优化方法- 首先这篇文章应该大家都看过吧-没看过的自行百度 关于实现的思路文章里都给好了-这篇就主要给一点题目啥的 (P.S. 电脑重装了,如果博客发出来有一些奇怪的问题不要在 ...

  9. Azure底层架构的初步分析

    之所以要写这样的一篇博文的目的是对于大多数搞IT的人来说,一般都会对这个topic很感兴趣,因为底层架构直接关乎到一个公有云平台的performance,其实最主要的原因是我们的客户对此也非常感兴趣, ...

随机推荐

  1. as3杂记

    一.内存回收方式: 1.引用计数[没有互相引用] 2.标记清除[fp自己检测是否引用,没有引用的清除] 二.通信方式: 1.http:小型页游[charles抓包查看] 2.socket:大型页游[W ...

  2. CodeForces - 566D Restructuring Company 并查集的区间合并

    Restructuring Company Even the most successful company can go through a crisis period when you have ...

  3. 割点(Tarjan算法)

    本文可转载,转载请注明出处:www.cnblogs.com/collectionne/p/6847240.html .本文未完,如果不在博客园(cnblogs)发现此文章,请访问以上链接查看最新文章. ...

  4. .NET Core 3.0之深入源码理解Configuration(三)

      写在前面 上一篇文章讨论了文件型配置的基本内容,本篇内容讨论JSON型配置的实现方式,理解了这一种配置类型的实现方式,那么其他类型的配置实现方式基本可以触类旁通.看过了上一篇文章的朋友,应该看得出 ...

  5. shell chpasswd 命令 修改用户密码

    使用useradd 命令增加一个用户后,它默认是没有设置密码的.如果需要给用户设置或者修改密码,一般会使用passwd命名. 但是passwd命令有一个缺陷,它需要人工交互操作. 如果你是一名系统管理 ...

  6. nacos启动

    nacos下载 https://github.com/alibaba/nacos 1.执行数据库脚本 2.修改配置文件application.propertiesspring.datasource.p ...

  7. C 语言实例 - 查找字符在字符串中出现的次数

    C 语言实例 - 查找字符在字符串中出现的次数 C 语言实例 C 语言实例 查找字符在字符串中的起始位置(索引值从 开始). 实例 #include <stdio.h> int main( ...

  8. day04 异常

  9. 在Ubuntu14.04 64位上安装Clion

    1.下载Clion 1.1 下载Linux版Clion的.tar.gz的压缩包 Clion 2017.3.1 下载安装:https://www.jetbrains.com/clion/download ...

  10. iOS开发:创建推送开发证书和生产证书,以及往极光推送官网上传证书的步骤方法

    在极光官网上面上传应用的极光推送证书的实质其实就是上传导出的p12文件,在极光推送应用管理里面,需要上传两个p12文件,一个是生产证书,一个是开发证书 ,缺一不可,具体如下所示: 在开发者账号里面创建 ...