Description

HB要办个签证,办证处是一座 M 层的大楼,每层楼都有 N 个办公室,编号为1..N,每个办公室有一个签证员,签证需要让第 M 层的某个签证员盖章才有效。每个签证员都要满足下面三个条件之一才会给HB盖章:

  1. 这个签证员在1楼。
  2. HB的签证已经给这个签证员的正楼下(房间号相同)的签证员盖过章了。
  3. HB的签证已经给这个签证员的相邻房间(房间号相差1,楼层相同)的签证员盖过章了。

每个签证员盖章都要收取一定费用,这个费用不超过1000000000。找出费用最小的盖章路线,使签证生效。

Input

第1行两个整数 M 和 N 。  接下来M行每行 N 个整数,第i行第j个数表示第i层的第j个签证员收取的费用。

Output

  输出最小的费用。

Sample Input 1

3 4
10 10 1 10
2 2 2 10
1 10 10 10

Sample Output 1

8

Hint

1<=M<=100,1<=N<=500

乍一看很简单,只需要设状态函数f(i,j)表示到第i层第j个房间需要的最小花费,转移方程:
\(f(i,j)=min(f(i-1,j),f(i,j-1),f(i,j+1))+a[i][j]\)
其中a[i][j]为当前房间的花费。
初始化
\(f(i,j)=inf\)
\(f(1,j)=a[1][j]|1<=j<=m\)

但是如果每一层这样去转移,无论是从左向右计算还是从右向左计算都有后效性,因为如果从左向右更新,那么计算f(i,j)时用到的f(i,j+1)还没有更新过,会引起错误

解决方法是每一层先从左向右走用f(i,j-1)更新f(i,j),走完这层再从右向左走用f(i,j+1)更新f(i,j),保证了计算时用到的数都不是未知的。

\(Ans=min(f(n,j)|1<=j<=m)\)
我的代码里是从上向下走的,区别不大

#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<iostream>
#include<list>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
#define inf 0x3f3f3f3f
using namespace std;
int n,m;
int a[105][505];
int f[105][505];
void init(){scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){scanf("%d",&a[i][j]);}}for(int i=0;i<=n+1;i++)for(int j=0;j<=m+1;j++)f[i][j]=inf;
}
void dp(){for(int i=1;i<=m;i++)f[n][i]=a[n][i];for(int i=n-1;i>=1;i--){for(int j=m;j>=1;j--)f[i][j]=min(f[i+1][j],f[i][j+1])+a[i][j];//合并右走和下走 for(int j=1;j<=m;j++)//分开循环防后效 f[i][j]=min(f[i][j],f[i][j-1]+a[i][j]);//左走 }int ans=inf;for(int i=1;i<=m;i++)ans=min(ans,f[1][i]);printf("%d",ans);
}
int main(){init();dp();return 0;
}

转载于:https://www.cnblogs.com/de-compass/p/11234809.html

cqyz oj | 【训练题】HB办证 P1419 | DP动态规划相关推荐

  1. 每日一题——拿金币(DP动态规划)

    学习目标: 每天睡前是否感到浑浑噩噩,一天又在不知不觉中过去,回想我今天都干了什么呢? 啊~我这一天又什么也没干,好有罪恶感啊,不行,我明天一定要好好学算法(手动狗头). 明日复明日,明日何其多?不要 ...

  2. 算法训练 K好数(dp+动态规划)

    问题描述 如果一个自然数N的K进制表示中任意的相邻的两位都不是相邻的数字,那么我们就说这个数是K好数.求L位K进制数中K好数的数目.例如K = 4,L = 2的时候,所有K好数为11.13.20.22 ...

  3. Tarjan相关最全(附训练题和答案)

    Tarjan相关最全(附训练题和答案) 算法思想 Tarjan 强连通分量 割点 割桥 缩点 Kosaraju Garbow 训练 POJ2186 POJ1236 POJ2375 Luogu P338 ...

  4. 二级计算机为让利消费者,计算机二级office题库训练题(2)

    D.计算机病毒是一个特殊的寄生程序 15. 以下关于编译程序的说法正确的是( ). A.编译程序属于计算机应用软件,所有用户都需要编译程序 B.编译程序不会生成目标程序,而是直接执行源程序 C.编译程 ...

  5. 职称计算机windows 7,2017职称计算机考试Windows训练题

    2017职称计算机考试Windows训练题 考试考点往往贯穿在平时我们练习的习题中,下面是小编给大家提供的职称计算机考试Windows训练题,大家可以参考练习,更多习题练习请关注应届毕业生考试网. 1 ...

  6. c语言编程思维训练50题,c语言逻辑思维训练题一

    c语言逻辑思维训练题一 (3页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 14.90 积分 要求:用java实现下面的所有题目,2012年11月1日提交 ...

  7. js逻辑训练题_二建冲刺必刷300题!精选历年真题+母子题+模考易错题!

    订阅公众号,回复[口诀],获取完整版实务口诀 你是不是常常疑惑为什么同样在做题,同样熬通宵,同样很努力,为什么有人顺利拿证,有人却因几分之差黯然落榜? 因为二建不仅拼努力的程度,更要拼对精准二建信息的 ...

  8. c语言中a lt 1e-9,年9月计算机二级考试C语言强化训练题

    年9月计算机二级考试C语言强化训练题 为了使广大学员在备战计算机二级考试时更快的掌握相应知识点,小编在此精选了计算机二级C语言的练习题供学员参考,大家要抓紧时间备考,祝大家备考愉快,梦想成真. 一.单 ...

  9. 计算机考试dw操作题,职称计算机考试Dreamweaver训练题

    职称计算机考试Dreamweaver训练题 在考试备考中,大家要多进行习题的练习,以保证知识的灵活运用,下面是小编给大家提供的职称计算机考试Dreamweaver训练题,大家可以参考练习. 训练题一: ...

最新文章

  1. matlab的默认字体_matlab默认字体设置
  2. Object Pascal 中类型
  3. 什么是整除,什么是素数
  4. python开发基础教程
  5. linux怎样用命令提示符,Linux用户必知:一分钟掌握14个常用Linux命令行快捷键
  6. 等额本息和等额本金,哪个还款方式更划算?
  7. Java面向对象编程学习
  8. Python高级——正则表达式与re模块
  9. linux mail使用笔记
  10. 阿里云Linux服务器Tomcat9.0的安装及配置
  11. OpenLayers 在Vue中增删改
  12. python写入日志文件时日志内容重复写入
  13. ADC RF中频采样 Vivado Verilog 联合 matlab 进行带通滤波器设计与仿真
  14. 纸壳cms php,纸壳CMS 3.4 发布,电商功能增强
  15. 2018网易编程射击游戏
  16. c++创建一个linux deamon进程
  17. 很全的电脑专业术语中英文对照
  18. 【机房重构】一步一步往上爬——不仅仅是三层
  19. 牛啊!2小时复现顶会论文,他的秘诀是——
  20. redis哨兵模式(docker)

热门文章

  1. EndNote: CQUPT 2023年硕士毕业论文的参考文献插入方法 仅供参考,其实很繁琐
  2. 遥仰凰华重装系统后无法运行解决方法
  3. 金融项目-注册和实名功能
  4. html5公开课宣传文案,《自信演讲》公开课文案
  5. 金蝶K3在采购订单下推外购入库单:没有符合条件的记录,处理方案
  6. “百变”Redis带你见识不同场景下的产品技术架构 1
  7. 把数字翻译成字符串python_把数字翻译成字符串(Python and C++解法)
  8. Linux --- 常用命令汇总
  9. 【软考软件评测师】2014年下案例分析历年真题
  10. 计算机应用简单的微课制作,《计算机应用基础》微课制作经验谈.doc