【做题笔记】P2327 [SCOI2005]扫雷
https://www.luogu.com.cn/problem/P2327
看到题解区一位 dalao 思路甚妙,很受启发,故整理了一下思路。
本人表述能力不强,如讲解不清还请见谅。
思路:
四维 DP,定义四维 fff 数组,第一维存储第二列数的位置 iii,第二、三、四维分别表示第一列 i−1i-1i−1 , iii , i+1i+1i+1 的位置有没有雷(定义 1 为有雷,0 为无雷)。
所以初始化为 f(0,0,0,0)=f(0,0,0,1)=1f(0,0,0,0)=f(0,0,0,1)=1f(0,0,0,0)=f(0,0,0,1)=1.
我们还能知道,aia_iai 影响的摆放雷的方案的位置 i+1i+1i+1 , iii 由 ai−1a_{i-1}ai−1 影响的摆放雷的方案的位置 iii , i+1i+1i+1 推来,那么转移思路就很好想了。
做法:
枚举第二列每一个数,因为棋盘是 n×2n\times2n×2 的大小,所以 aia_iai 不能大于 4,所以分以下四种情况讨论:
1.当 ai=0a_i=0ai=0 时,此时状态为 f(i,0,0,0)f(i,0,0,0)f(i,0,0,0).
由 ai−1a_{i-1}ai−1 转移时,只有 f(i−1,1,0,0)f(i-1,1,0,0)f(i−1,1,0,0) 和 f(i−1,0,0,0)f(i-1,0,0,0)f(i−1,0,0,0) 两种情况.
所以 f(i,0,0,0)=f(i−1,1,0,0)+f(i−1,0,0,0)f(i,0,0,0)=f(i-1,1,0,0)+f(i-1,0,0,0)f(i,0,0,0)=f(i−1,1,0,0)+f(i−1,0,0,0).
2.当 ai=1a_i=1ai=1 时,此时有三种状态,分别为 f(i,1,0,0)f(i,1,0,0)f(i,1,0,0),f(i,0,1,0)f(i,0,1,0)f(i,0,1,0),f(i,0,0,1)f(i,0,0,1)f(i,0,0,1).
易得 f(i,1,0,0)=f(i−1,0,1,0)+f(i−1,1,1,0)f(i,1,0,0)=f(i-1,0,1,0)+f(i-1,1,1,0)f(i,1,0,0)=f(i−1,0,1,0)+f(i−1,1,1,0)
f(i,0,1,0)=f(i−1,0,0,1)+f(i−1,1,0,1)f(i,0,1,0)=f(i-1,0,0,1)+f(i-1,1,0,1)f(i,0,1,0)=f(i−1,0,0,1)+f(i−1,1,0,1)
f(i,0,0,1)=f(i−1,0,0,0)+f(i−1,1,0,0)f(i,0,0,1)=f(i-1,0,0,0)+f(i-1,1,0,0)f(i,0,0,1)=f(i−1,0,0,0)+f(i−1,1,0,0)
3.当 ai=2a_i=2ai=2 时,此时有三种状态,分别为 f(i,1,1,0)f(i,1,1,0)f(i,1,1,0),f(i,0,1,1)f(i,0,1,1)f(i,0,1,1),f(i,1,0,1)f(i,1,0,1)f(i,1,0,1).
易得 f(i,1,1,0)=f(i−1,1,1,1)+f(i−1,0,1,1)f(i,1,1,0)=f(i-1,1,1,1)+f(i-1,0,1,1)f(i,1,1,0)=f(i−1,1,1,1)+f(i−1,0,1,1)
f(i,0,1,1)=f(i−1,1,0,1)+f(i−1,0,0,1)f(i,0,1,1)=f(i-1,1,0,1)+f(i-1,0,0,1)f(i,0,1,1)=f(i−1,1,0,1)+f(i−1,0,0,1)
f(i,1,0,1)=f(i−1,0,1,0)+f(i−1,1,1,0)f(i,1,0,1)=f(i-1,0,1,0)+f(i-1,1,1,0)f(i,1,0,1)=f(i−1,0,1,0)+f(i−1,1,1,0)
4.当 ai=3a_i=3ai=3 时,此时状态只能为 f(i,1,1,1)f(i,1,1,1)f(i,1,1,1).
易得 f(i,1,1,1)=f(i−1,1,1,1)+f(i−1,0,1,1)f(i,1,1,1)=f(i-1,1,1,1)+f(i-1,0,1,1)f(i,1,1,1)=f(i−1,1,1,1)+f(i−1,0,1,1)
转移过程推完了,输出结果需要根据 ana_nan 判断。
因为 ana_nan 不能等于 3(在最后一格,只能在其左侧和左上放雷),所以分 0,1,2 三种情况讨论即可:
1.当 an=0a_n=0an=0 时,摆放方式只有一种,所以直接输出 f(n,0,0,0)f(n,0,0,0)f(n,0,0,0).
2.当 an=1a_n=1an=1 时,此时有两种摆法,分别为 f(i,1,0,0)f(i,1,0,0)f(i,1,0,0),f(i,0,1,0)f(i,0,1,0)f(i,0,1,0).所以输出它们的和,即 f(i,1,0,0)+f(i,0,1,0)f(i,1,0,0)+f(i,0,1,0)f(i,1,0,0)+f(i,0,1,0).
3.当 ai=2a_i=2ai=2 时,此时摆法只能为 f(n,1,1,0)f(n,1,1,0)f(n,1,1,0),所以直接输出 f(n,1,1,0)f(n,1,1,0)f(n,1,1,0).
简单易懂的代码:
#include<iostream>
#include<cstdio>
#include<cstdlib>
using namespace std;
const int MAXN=1e4+10;
int arr[MAXN],f[MAXN][2][2][2],ans;
int main(){int n;scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&arr[i]);f[0][0][0][0]=f[0][0][0][1]=1;for(int i=1;i<=n;i++){if(!arr[i])f[i][0][0][0]=f[i-1][1][0][0]+f[i-1][0][0][0];if(arr[i]==1){f[i][1][0][0]=f[i-1][0][1][0]+f[i-1][1][1][0];f[i][0][1][0]=f[i-1][0][0][1]+f[i-1][1][0][1];f[i][0][0][1]=f[i-1][0][0][0]+f[i-1][1][0][0];}if(arr[i]==2){f[i][1][1][0]=f[i-1][0][1][1]+f[i-1][1][1][1];f[i][1][0][1]=f[i-1][0][1][0]+f[i-1][1][1][0];f[i][0][1][1]=f[i-1][0][0][1]+f[i-1][1][0][1];}if(arr[i]==3)f[i][1][1][1]=f[i-1][0][1][1]+f[i-1][1][1][1];}if(!arr[n]) cout<<f[n][0][0][0];else if(arr[n]==1) cout<<f[n][1][0][0]+f[n][0][1][0];else if(arr[n]==2) cout<<f[n][1][1][0];return 0;
}
【做题笔记】P2327 [SCOI2005]扫雷相关推荐
- 洛谷 P2327 [SCOI2005]扫雷
PS:如果读过题了可以跳过题目描述直接到题解部分 提交链接:洛谷 P2327 [SCOI2005]扫雷 题目 题目描述 相信大家都玩过扫雷的游戏.那是在一个 n*m 的矩阵里面有一些雷,要你根据一些信 ...
- C语言程序设计做题笔记之C语言基础知识(下)
C 语言是一种功能强大.简洁的计算机语言,通过它可以编写程序,指挥计算机完成指定的任务.我们可以利用C语言创建程序(即一组指令),并让计算机依指令行 事.并且C是相当灵活的,用于执行计算机程序能完成的 ...
- verilog练习:hdlbits网站上的做题笔记(6)
前言 之前的文章<如何学习verilog,如何快速入门?>中提到了verilog学习,推荐了一个可以练习的网站:hdlbits网站,那自己也玩玩这个网站. 这篇文章,是接着<veri ...
- verilog练习:hdlbits网站上的做题笔记(5)
前言 之前的文章<如何学习verilog,如何快速入门?>中提到了verilog学习,推荐了一个可以练习的网站:hdlbits网站,那自己也玩玩这个网站. 这篇文章,是接着<veri ...
- 洛谷 P2327 [SCOI2005] 扫雷
题目描述 输入输出格式 输入格式: 第一行为N,第二行有N个数,依次为第二列的格子中的数.(1<= N <= 10000) 输出格式: 一个数,即第一列中雷的摆放方案数. 输入输出样例 输 ...
- verilog练习:hdlbits网站上的做题笔记(7)!强烈推荐!
前言 之前的文章<如何学习verilog,如何快速入门?>中提到了verilog学习,推荐了一个可以练习的网站:hdlbits网站,那自己也玩玩这个网站. 这篇文章,是接着<veri ...
- verilog练习:hdlbits网站上的做题笔记(8)
前言 之前的文章<如何学习verilog,如何快速入门?>中提到了verilog学习,推荐了一个可以练习的网站:hdlbits网站,那自己也玩玩这个网站. 这篇文章,是接着<veri ...
- 洛谷P2327 [SCOI2005]扫雷 [2017年5月计划 清北学堂51精英班Day1]
P2327 [SCOI2005]扫雷 题目描述 输入输出格式 输入格式: 第一行为N,第二行有N个数,依次为第二列的格子中的数.(1<= N <= 10000) 输出格式: 一个数,即第一 ...
- buuctf-MISC篇做题笔记(2)
buuctf-MISC篇做题笔记(2) 第七题:基础破解 先看题目提示,可能也要暴力破解 打开后是RAR文件,需要密码 我是用RARpassword暴力破解,且根据题意已知是四位纯数字密码,设置破解的 ...
- 关于数据库设计的做题笔记——选择题+填空题+大题
✅ 一点整理后的做题笔记- 文章目录 一.选择题和填空题 二.大题 三.写后感 ● 我们用的教材: 一.选择题和填空题 逻辑设计阶段的任务包括设计视图,形成数据库的外模式.( ) A. 对 B. 错 ...
最新文章
- python代码基础题-python每日经典算法题5(基础题)+1(中难题)
- Python 新浪微博 各种表情使用频率
- 批量替换 MySQL 指定字段中的字符串
- c语言递归汉诺塔次数,汉诺塔问题(C语言经典递归问题(一))
- 从零开始学前端:伪元素和盒子模型 --- 今天你学习了吗?(CSS:Day13)
- 20145234黄斐《信息安全系统设计基础》第十周
- c++类成员变量初始化详解
- 软件工程第二篇博客(“相等”)
- 中国移动MM如何成就千亿梦想
- 轻松搞定iOS自动化环境搭建
- HTML中哪些标记能放在首部,HTML基本结构与常用标记
- 获取软件的apk包名、查看手机设备名称等
- c语言知识点总结300字,大二学年自我总结300字 .doc
- OpenWrt之DNS域名解析系统(/etc/resolv.conf)
- 弹力弹珠java_Java趣味小程序:打弹珠
- “POW'ER 2020 DEFI 创新者大会” | Conflux CTO 伍鸣畅谈公链如何成为 DeFi 的完美世界...
- 使用vite插件编写tsx文件
- C语言实现简单的ai麻将对局(较大工程,持续更新ing)
- Github标星5.3K,进阶学习工作最全指南
- C语言中单引号 39 97 39,C語言程序设计实验指导书.doc
热门文章
- linux如何添加360网站卫士ip,使用加速乐、360网站卫士PHP无法获取用户IP的解决方法...
- 若有下列共用体定义_若有下列共用体定义:
- 用C语言实现简单的神经元
- linux网桥转发自身数据,linux网桥理解之一
- 数据库作业 1:绘制crow‘s foot图
- DRV8301驱动芯片BUCK电路设计
- 古代的电子计算机,古代也有黑科技:周朝的智能机器人,元朝的电子计算机!...
- python定义匿名函数关键字_Python匿名函数
- 公众号留言板怎么开通
- 【Python】爬取百度图片和必应图片