当前位置: 首页 > news >正文

P5003 跳舞的线 - 乱拐弯

挺水的棋盘dp题目类型

虽然说水,但是我今晚快一个多小时卡在这道题上面。这反映了我对这类dp的不熟悉。


这道题一看上去就知道应该是要dp的,每一步只能走右或走下就已经提示给你要这么转移。

做dp首先想明白怎么定义状态:

dp[i][j][0/1]表示当前走到\(i\)\(j\)列,目前的朝向向右(0)或向下(1)的最大或最小操作数。

这里是我最没有想到的转移环节:

当目前朝向朝右的时候,你只能够从\((i,j-1)\)这个点处转移来,决策就两个:拐弯或不拐弯。

同理,当现在朝下的时候只能从她上面转移而来。

这样,每一个点的转移就只有两个取值。

当然,障碍我们就不用转移了,直接忽略掉让她是memset上的极大值或极小值就可以了。

最后如何判断有解?

我的做法是判断那个最大的步数是否大于0,因为初始化是极小值,所以如果不大于0就无法到达。

当然也可以开局就跑个dfs来专门判断。

代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using std::max;
using std::min;
const int maxn = 1005;
const int _INF = -1886417009;
const int INF = 0x3f3f3f3f;
int dpmax[maxn][maxn][2];// 0: right, 1: down
int dpmin[maxn][maxn][2];
char ch[maxn][maxn];
int n, m;

int main()
{
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++)
    {
        scanf("%s", ch[i] + 1);
    }
    memset(dpmax, 0x8f, sizeof dpmax);
    memset(dpmin, 0x3f, sizeof dpmin);
    for(int i = 1; i <= n; i++)
    {
        if(ch[i][1] == '#') break;
        dpmax[i][1][1] = dpmin[i][1][1] = 0;
        dpmax[i][1][0] = dpmin[i][1][0] = 1;
    }
    for(int i = 1; i <= m; i++)
    {
        if(ch[1][i] == '#') break;
        dpmax[1][i][0] = dpmin[1][i][0] = 0;
        dpmax[1][i][1] = dpmin[1][i][1] = 1;
    }
    for(int i = 2; i <= n; i++)
    {
        for(int j = 2; j <= m; j++)
        {
            if(ch[i][j] == '#') continue;
            dpmax[i][j][0] = max(dpmax[i][j-1][1] + 1, dpmax[i][j-1][0]);
            dpmax[i][j][1] = max(dpmax[i-1][j][0] + 1, dpmax[i-1][j][1]);
            dpmin[i][j][0] = min(dpmin[i][j-1][1] + 1, dpmin[i][j-1][0]);
            dpmin[i][j][1] = min(dpmin[i-1][j][0] + 1, dpmin[i-1][j][1]);
        }
    }
    
    int maxans = max(dpmax[n][m][0], dpmax[n][m][1]);
    int minans = min(dpmin[n][m][0], dpmin[n][m][1]);
    if(maxans < 0) printf("-1\n");
    else printf("%d %d\n", maxans, minans);
    
    /*
    while(233)
    {
        int x, y, z; scanf("%d%d%d", &x, &y, &z);
        printf("%d\n", dpmax[x][y][z]);
    }
    */
    return 0;
}

转载于:https://www.cnblogs.com/Garen-Wang/p/9919094.html

相关文章:

  • 阿里数据库十年变迁,那些你不知道的二三事
  • RTSP(Real Time Streaming Protocol)实时流传输协议详解
  • 《三块广告牌》
  • 【重磅】Spring Boot 2.1.0 权威发布
  • Laravel Telescope:优雅的应用调试工具
  • iOS 传感器集锦
  • 2018-2019-1 20165323 《信息安全系统设计基础》第七周学习总结
  • elasticsearch Query DSL(三)
  • 在 centos 上安装 Jenkins
  • 以太坊生态系统中的开发工具和技术
  • git命令——revert、reset
  • 如何高效的使用 Git
  • opencv模板匹配有趣的链接
  • 好看的字体—方正粗倩
  • PAT 1041 Be Unique[简单]
  • C++回声服务器_9-epoll边缘触发模式版本服务器
  • Fundebug计费标准解释:事件数是如何定义的?
  • github指令
  • Intervention/image 图片处理扩展包的安装和使用
  • JavaScript设计模式系列一:工厂模式
  • QQ浏览器x5内核的兼容性问题
  • React-redux的原理以及使用
  • SpringCloud(第 039 篇)链接Mysql数据库,通过JpaRepository编写数据库访问
  • tab.js分享及浏览器兼容性问题汇总
  • vuex 笔记整理
  • XForms - 更强大的Form
  • 如何使用 OAuth 2.0 将 LinkedIn 集成入 iOS 应用
  • 用Node EJS写一个爬虫脚本每天定时给心爱的她发一封暖心邮件
  • 你对linux中grep命令知道多少?
  • 3月27日云栖精选夜读 | 从 “城市大脑”实践,瞭望未来城市源起 ...
  • mysql 慢查询分析工具:pt-query-digest 在mac 上的安装使用 ...
  • postgresql行列转换函数
  • ​DB-Engines 12月数据库排名: PostgreSQL有望获得「2020年度数据库」荣誉?
  • # Panda3d 碰撞检测系统介绍
  • # 数论-逆元
  • #HarmonyOS:软件安装window和mac预览Hello World
  • #基础#使用Jupyter进行Notebook的转换 .ipynb文件导出为.md文件
  • %check_box% in rails :coditions={:has_many , :through}
  • (js)循环条件满足时终止循环
  • (办公)springboot配置aop处理请求.
  • (超简单)使用vuepress搭建自己的博客并部署到github pages上
  • (论文阅读笔记)Network planning with deep reinforcement learning
  • (十三)Flask之特殊装饰器详解
  • (一)ClickHouse 中的 `MaterializedMySQL` 数据库引擎的使用方法、设置、特性和限制。
  • (一一四)第九章编程练习
  • (转)为C# Windows服务添加安装程序
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件
  • .net 托管代码与非托管代码
  • .NET 中使用 Mutex 进行跨越进程边界的同步
  • .NET/C# 使用反射调用含 ref 或 out 参数的方法
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)...
  • .netcore 如何获取系统中所有session_ASP.NET Core如何解决分布式Session一致性问题
  • .net反编译工具
  • .NET平台开源项目速览(15)文档数据库RavenDB-介绍与初体验
  • .net之微信企业号开发(一) 所使用的环境与工具以及准备工作