P1713 麦当劳叔叔的难题

题目描述

说我们铭铭小朋友成功的回答了爸爸的问题,自然少不了要去索要些奖励,抠门的爸爸一看报纸,嘿,门口的麦当劳在搞活动,还有免费午餐哦,不过前提条件:得正确回答麦当劳叔叔的问题。

问题是这样描述的:

“我面前有很多个小朋友,我希望你帮我找到一个最聪明的小朋友。我心目中最聪明的就是第一个跑进麦当劳大门的,我希望你帮我找出最聪明和最不聪明的小朋友,可能的最大的到达时间差。但是,小朋友只能按照一个特殊的规则前进。小朋友面前有一个 n\times nn×n 的格子矩阵,左下角的格子是起点,右上角的格子是大门。每个孩子每秒可以走向 上、下、左、右 前进一个格子,每个格子只能经过一次。但矩阵中间有一些障碍区,不能通过,只能绕过。”

例如,4\times 44×4 的矩阵,格子 (1, 1),(2, 3),(4, 2)为障碍区,黑格子就是一条可行的路线。时间为 77。

输入格式
第一行为两个整数 n, m

第二至第 m+1行里,每行描述一个障碍区。用两个整数表示 x, y

输出格式
仅一行,那个最大的时间差。

输入输出样例
输入 #1复制
4 3
1 1
2 3
4 2
输出 #1复制
4
说明/提示
2\le n\le 102≤n≤10,0\le m\le 1000≤m≤100,1\leq x,y\leq n1≤x,y≤n
计算最短路是容易的,考虑计算最长路。可令 dp_{i,j,S}
表示考虑到格子 (i,j)轮廓线上的插头方案为 S 时的最长路径。

考虑 S 需要记录哪些信息,发现只需要维护插头之间的连通性,使合并插头的时候不连出环即可。也就是我们可以用一个长为 n+1 的数组 A表示 S,A_i = 0


=0 表示当前位置没有插头,A_i = 1
=1 表示当前插头和源点联通,否则如果 A_i > 1A

表示插头 ii 和 jj 联通。采用最小表示法即可使 S 对应的 A 唯一。

上图轮廓线的状态对应的 A = [0,0,2,3,3,0,2,1]

考虑 SS 的可能状态数,发现:

1.对于 x > 1x>1,只可能存在 0 个或者 2 个 i 满足 A_i = xA

2.不存在 i < j < k < li<j<k<l 且 A_i = A_kA
也即 A_i >

1 的位置一定可以表示为一个合法的括号序列,那么可以得到状态数是低于 3^n
n
的。事实上状态数是低于这个界的。因此以上算法的时间复杂度为 O(n^c 3^n ),其中 c 为一取决于实现方式的常数。

(下面的代码需要 C++11)

#include <bits/stdc++.h>

using pii = std::pair<int,int>;
const int inf = 1e7;

int dx[] = {0,1,0,-1};
int dy[] = {1,0,-1,0};

int n,m,dis[12][12],ban[12][12];

std::map< std::vector<int> , int >dp[12][12];	

std::vector<int> process(std::vector<int>S) {
	int cnt = 1;
	int vis[30] = {0};
	for (int i = 1; i <= n + 1; ++ i) {
		if (S[i] == 0 || S[i] == 1) continue;
		if (!vis[S[i]]) { vis[S[i]] = ++cnt; S[i] = cnt; }
		else S[i] = vis[S[i]];
	} return S;
}
std::vector<int> shift(std::vector<int>S){ for (int i = 1; i <= n; ++ i) S[i] = S[i+1]; S[n+1] = 0; return S; }
std::vector<int> trans(std::vector<int>S,int i) { std::swap(S[i],S[i+1]); return S; }
std::vector<int> create(std::vector<int>S,int i) { S[i] = S[i+1] = 20; return process(S); }
std::vector<int> merge(std::vector<int>S,int i) {
	int p = S[i], q = S[i+1], flag = 20;
	if (p == 1 || q == 1) flag = 1;
	for (int i = 1; i <= n + 1; ++ i) if (S[i] == p || S[i] == q) S[i] = flag;
	S[i] = S[i+1] = 0;
	return process(S);
}

int main() {
	
	scanf("%d%d",&n,&m);
	for (int i = 1; i <= m; ++ i) {
		int x,y;
		scanf("%d%d",&x,&y);
		ban[x][y] = 1;
		assert( not ( (x == 1 && y == n)  or (x == n && y == 1) ) );
	}
	
	auto bfs = [&]() {
		std::memset(dis,-1,sizeof(dis));
		std::queue< pii >q;
		q.push( { 1,n } );
		dis[1][n] = 0;
		while (q.size()) {
			auto u = q.front(); q.pop();
			int x = u.first, y = u.second;
			for (int i = 0; i < 4; ++ i) {
				int x1 = x + dx[i], y1 = y + dy[i];
				if (x1 < 1 || x1 > n || y1 < 1 || y1 > n || dis[x1][y1] != -1 || ban[x1][y1]) continue;
				dis[x1][y1] = dis[x][y] + 1;
				q.push( { x1,y1 } );
			}
		} 
	};  bfs();
	
	std::vector<int>v(n+2);
	v[n+1] = 1; dp[1][n-1][v] = 1;
	v[n+1] = 0; v[n] = 1; dp[1][n-1][v] = 1;
	
	for (int i = 1; i <= n; ++ i) {
		for (int j = n - (i == 1); j >= 1; j --) {
			for (auto P:dp[i][j]) {
				auto S = P.first; int v = P.second;
				int p = S[j], q = S[j+1];
				if (p == 0 && q == 0) dp[i][j-1][S] = std::max(dp[i][j-1][S],v);
				if (ban[i][j]) continue;
				if (p == 0 && q == 0) {
					auto T = create(S,j);
					dp[i][j-1][T] = std::max(dp[i][j-1][T],v + 1);
				}
				if ((p != 0) + (q != 0) == 1) {
					dp[i][j-1][S] = std::max(dp[i][j-1][S],v + 1);
					auto T = trans(S,j);
					dp[i][j-1][T] = std::max(dp[i][j-1][T],v + 1);
				}
				if (p && q && p != q) {
					auto T = merge(S,j);
					dp[i][j-1][T] = std::max(dp[i][j-1][T],v + 1);
				}
			}
		} for (auto P:dp[i][0]) {
			auto S = P.first; int v = P.second;
			if (S[1] == 0) dp[i+1][n][shift(S)] = dp[i][0][S];
		}
	}
	std::vector<int>S1(n+2),S2(n+2);
	S1[1] = 1; S2[2] = 1;
	printf("%d",std::max(dp[n][1][S1],dp[n][1][S2]) - dis[n][1]);
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/601532.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

测试平台开发:Django开发实战之注册界面实现(下)

1、 评论和用户建立关联 1&#xff09;修改model: 软关联还是硬关联默认值是什么关联方被删除怎么办如何根据评论找到用户如何根据用户找到评论 然后执行命令&#xff1a; pdm run M pdm run init 这样在表里面就会多一个user_id的字段 2&#xff09;修改视图&#xf…

一个故事就能够教会你看懂各种锁

我是一个线程&#xff0c;一个卖票程序的线程。 自从我们线程诞生以来&#xff0c;同一个进程地址空间里允许有多个执行流一起执行&#xff0c;效率提升的同时&#xff0c;也引来了很多麻烦。 我们卖票线程的工作很简单&#xff0c;比如票的总数是100&#xff0c;每卖一张就减…

LabelImg下载及目标检测数据标注

为什么这一部分内容这么少会单独拎出来呢&#xff0c;因为后期会接着介绍YOLOv8中的其他任务&#xff0c;会使用其他软件进行标注&#xff0c;所以就单独区分开来每一个任务的标注方式了。 这一部分就介绍目标检测任务的标注&#xff0c;数据集是我从COCO2017Val中抽出来两类&a…

H5视频付费点播打赏影视系统程序全开源运营版

这是一款视频打赏源码&#xff0c;勿做非法用途&#xff0c;由用户亲测功能完善&#xff0c;源码仅用于学习使用&#xff0c;分享链接是用户云盘&#xff0c;具有时效性&#xff0c;感兴趣的可以去学习。 thinkphp开发&#xff0c;前后端分离设计&#xff0c;支持游客登陆、VIP…

经典的设计模式和Python示例(一)

目录 一、工厂模式&#xff08;Factory Pattern&#xff09; 二、单例模式&#xff08;Singleton Pattern&#xff09; 三、观察者模式&#xff08;Observer Pattern&#xff09; 一、工厂模式&#xff08;Factory Pattern&#xff09; 工厂模式&#xff08;Factory Pattern…

牛客网刷题 | BC79 小乐乐求和

目前主要分为三个专栏&#xff0c;后续还会添加&#xff1a; 专栏如下&#xff1a; C语言刷题解析 C语言系列文章 我的成长经历 感谢阅读&#xff01; 初来乍到&#xff0c;如有错误请指出&#xff0c;感谢&#xff01; 描述 小乐乐最近接触了求…

java-springboot项目添加swagger2/Knife4j,附注解

文章目录 添加依赖config工作包中新增SwaggerConfig报错注解 环境&#xff1a; jdk1.8 java8 springboot2.6.13 swagger2.9.2 添加依赖 pom.xml <!-- 添加swagger2--><dependency><groupId>io.springfox</groupId><artifactId>springfo…

函数编辑器调研及设计开发

前言&#xff1a;在产品研发中需要一款可嵌入web开发的代码及函数编辑器&#xff0c;本文从功能&#xff0c;扩展&#xff0c;外观/交互&#xff0c;维护/社区&#xff0c;兼容性&#xff0c;开源与否等方面考虑&#xff0c;进行对比筛选 1、编辑器统计数据 市面上编辑器有很…

【管理篇】如何提升管理中的沟通效率?

目录标题 管理沟通那些事如何提升沟通效率?&#x1f525;如何提升沟通技能&#xff1f; 向上沟通、员工激励和团队凝聚力提升 是管理沟通上比较难得问题 管理沟通那些事 管理沟通让技术管理者们痛苦的主因是确定性和规则性的减弱&#xff0c;不确定性的大幅度上升&#xff0c…

微软正在自主构建一个名为 MAI-1 的大型语言模型(不依赖 OpenAI)

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

IDEA中向Data Sources导入sql文件

IDEA中向Data Sources导入sql文件 开篇 在学习黑马的课程时&#xff0c;时常需要向数据库中导入sql文件生成数据库表&#xff0c;每次都会忘记导入步骤&#xff0c;折腾许久&#xff0c;于是将过程记录下来。 步骤 在Database中选择你要导入的数据库源&#xff0c;如图我想…

Matlab图像中加入脉冲噪声、高斯噪声并用均值滤波、中值滤波进行滤波处理

一、脉冲噪声和高斯噪声简介 脉冲噪声和高斯噪声是两种常见的信号干扰类型&#xff0c;它们的特性和影响各不相同&#xff1a; 脉冲噪声&#xff08;Impulse Noise&#xff09;&#xff1a; 在图像中&#xff0c;脉冲噪声表现为随机出现的亮点或暗点&#xff0c;这些噪声点通常…

[开发|鸿蒙] DevEco Studio编译构建(笔记,持续更新)

构建体系 编译构建是将应用/服务的源代码、资源、第三方库等&#xff0c;通过编译工具转换为可直接在硬件设备上运行的二进制机器码&#xff0c;然后再将二进制机器码封装为HAP/APP软件包&#xff0c;并为HAP/APP包进行签名的过程。其中&#xff0c;HAP是可以直接运行在模拟器…

FIFO Generate IP核使用——同步复位

在描述FIFO&#xff08;First In First Out&#xff09;或其他存储结构的同步复位&#xff08;Synchronous Reset&#xff09;功能时&#xff0c;srst&#xff08;或wr_rst/rd_rst&#xff0c;即写入和读取时钟域的同步复位信号&#xff09;仅适用于块RAM&#xff08;Block RAM…

企业为什么需要主数据管理工具?十大热门主数据管理工具盘点

主数据管理是一套综合性的策略和技术&#xff0c;用于协调和管理企业内用于识别关键业务实体&#xff08;如客户、产品、供应商和员工&#xff09;的一致性、准确性和统一性的数据。主数据管理的目的是创建一个“单一真相源”&#xff0c;确保在不同部门和系统之间共享的数据保…

AI预警未来:山体滑坡与塌方事故的潜在发现者

在科技日新月异的今天&#xff0c;人工智能&#xff08;AI&#xff09;的应用已经渗透到了我们生活的各个领域。而在防灾减灾的领域中&#xff0c;AI技术的引入无疑为我们打开了一扇新的大门。以梅大高速大埔往福建方向K11900m附近发生的路面塌方灾害为例&#xff0c;我们不禁思…

未授权访问:Redis未授权访问漏洞

目录 1、漏洞原理 2、环境搭建 3、未授权访问 4、利用redis未授权写入weshell 5、利用redis未授权反弹shell 6、利用redis未授权实现免密登录 防御手段 从这篇文章开始我就要开始学习各种未授权访问的知识和相关的实操实验了&#xff0c;一共有好多篇&#xff0c;内容主…

navicat premium16.3.9重置

软件下载 官网地址&#xff1a;https://navicat.com.cn/products/ # 准备脚本 1、建一个txt 2、复制以下代码 3、修改文件格式为bat 4、运行bat文件 5、重新打开navicat&#xff0c;试用期重置为14 经测试16.2.3以上版本均可用 echo off set dnInfo set dn2ShellFolder set r…

YOLOv8改进 | 主干篇 | 2024.5全新的移动端网络MobileNetV4改进YOLOv8(含MobileNetV4全部版本改进)

一、本文介绍 本文给大家带来的改进机制是MobileNetV4&#xff0c;其发布时间是2024.5月。MobileNetV4是一种高度优化的神经网络架构&#xff0c;专为移动设备设计。它最新的改动总结主要有两点&#xff0c;采用了通用反向瓶颈&#xff08;UIB&#xff09;和针对移动加速器优化…

用脚本写一个日期样式的字符

现在想要诸如此类样式的语句&#xff1a;&#xff08;过去三个月的&#xff09; 可以用python脚本写&#xff1a; from datetime import date, timedelta# 获取当前日期 current_date date.today()# 定义过去三个月的时间间隔 three_months_ago current_date - timedelta(da…
最新文章