题干:

相信大家都玩过扫雷的游戏。那是在一个n*m的矩阵里面有一些雷,要你根据一些信息找出雷来。万圣节到了
,“余”人国流行起了一种简单的扫雷游戏,这个游戏规则和扫雷一样,如果某个格子没有雷,那么它里面的数字
表示和它8连通的格子里面雷的数目。现在棋盘是n×2的,第一列里面某些格子是雷,而第二列没有雷,如下图: 
由于第一列的雷可能有多种方案满足第二列的数的限制,你的任务即根据第二列的信息确定第一列雷有多少种摆放
方案。

Input

  第一行为N,第二行有N个数,依次为第二列的格子中的数。(1<= N <= 10000)

Output

  一个数,即第一列中雷的摆放方案数。

Sample Input

2 1 1

Sample Output

2

Hint

解题报告:

简单但是十分不错的dp题。

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 10000 + 5;
ll dp[MAX][2][2];//dp[i][j][k]截止第i行,这一行为j,上一行为k。
int a[MAX];
int main()
{int n;cin>>n;for(int i = 1; i<=n; i++) scanf("%d",a+i);
//  if(a[1] != 0) {dp[1][1][0]=dp[1][1][1]=dp[1][0][0]=dp[1][0][1]=1;
//  }
//  dp[1][0][0] = dp[1][1][0]=1;//dp[][这行][上行]   dp[i行][i行][i-1行]for(int i = 2; i<=n+1; i++) {if(a[i-1] == 1) {dp[i][1][0] += dp[i-1][0][0];dp[i][0][0] += dp[i-1][0][1];dp[i][0][1] += dp[i-1][1][0];//默认其余的为0.。 }if(a[i-1] == 0) {dp[i][0][0] += dp[i-1][0][0];}if(a[i-1] == 2) {dp[i][1][0] += dp[i-1][0][1];dp[i][1][1] += dp[i-1][1][0];dp[i][0][1] += dp[i-1][1][1];}if(a[i-1] == 3) {dp[i][1][1] += dp[i-1][1][1];}}ll ans = 0;ans = /*dp[n+1][1][0] + dp[n+1][1][1] +*/ dp[n+1][0][0] + dp[n+1][0][1];printf("%lld\n",ans);return 0 ;}

总结:

注意合法状态和不更新状态的区别!!!有的是非法状态(此题中就要是0而不是INF,因为表示的是方法数),有的是不更新状态(此题中也是0,但是是无法到达状态,而不是非法状态),也就是,都是0但是含义不同!!

之所以更新成1,也是因为方法数是1。(只选这一种方法,所以方法数是1啊)

其实这个代码是不对的(虽然也AC了),初始化状态的时候应该用下面那个注释掉的,因为不然的话输入1 1就会错。,。。

注意不能输出dp[n][][]的四个状态的和!!!因为那样就不一定满足第n行的性质了!!!所以一定要让状态转移结束以后再找结果!!不能直接输出第n行的四个状态的和。

附一种解法:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
ll n,x,y,c;
const int MAX = 10000 + 5;
ll dp[MAX][2][2];//dp[i][j][k]截止第i行,这一行为j,上一行为k。
int a[MAX];
int main() {int n;cin>>n;for(int i = 1; i<=n; i++) scanf("%d",a+i);dp[1][0][0] = dp[1][1][0]=1;//dp[][这行][上行]   dp[i行][i行][i-1行]for(int i = 2; i<=n+1; i++)for(int las = 0 ; las <= 1 ; las++)for(int llas = 0; llas<=1; llas++)for(int now = 0; now<=1; now++)if(las+llas+now == a[i-1])dp[i][now][las] += dp[i-1][las][llas] ;ll ans = dp[n+1][0][0] + dp[n+1][0][1];printf("%lld\n",ans);return 0 ;
}

或者:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
ll n,x,y,c;
const int MAX = 10000 + 5;
ll dp[MAX][2][2];//dp[i][j][k]截止第i行,这一行为j,上一行为k。
int a[MAX];
int main() {int n;cin>>n;for(int i = 1; i<=n; i++) scanf("%d",a+i);dp[0][0][0] = dp[0][1][0]=1;//dp[][下一行][这一行行]   dp[i行][i+1行][i行]for(int i = 1; i<=n; i++)for(int las = 0 ; las <= 1 ; las++)for(int llas = 0; llas<=1; llas++)for(int now = 0; now<=1; now++)if(las+llas+now == a[i])dp[i][now][las] += dp[i-1][las][llas] ;ll ans = dp[n][0][0] + dp[n][0][1];printf("%lld\n",ans);return 0 ;
}

【HYSBZ - 1088 】扫雷Mine (简单dp)相关推荐

  1. BZOJ 1088: [SCOI2005]扫雷Mine( )

    枚举第一个的情况...判断一下是否冲突... ------------------------------------------------------------------ #include&l ...

  2. bzoj1088[SCOI2005]扫雷Mine

    1088: [SCOI2005]扫雷Mine Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 4284  Solved: 2552 [Submit][ ...

  3. POJ1088:滑雪(简单dp)

    题目链接:  http://poj.org/problem?id=1088 题目要求: 一个人可以从某个点滑向上下左右相邻四个点之一,当且仅当高度减小.求可以滑落的最长长度. 题目解析: 首先要先排一 ...

  4. 【思路】扫雷MINE

    题目(牛客网NC20241 [SCOI2005]扫雷MINE) 相信大家都玩过扫雷的游戏.那是在一个n*m的矩阵里面有一些雷,要你根据一些信息找出雷来. 万圣节到了 ,"余"人国流 ...

  5. [SCOI2005]扫雷MINE

    [SCOI2005]扫雷MINE 这道题算是一道思维题吧,如果没想好的话,代码肯定是不好敲的,好了,我们一起来看看题意吧: 题目描述 相信大家都玩过扫雷的游戏.那是在一个n*m的矩阵里面有一些雷,要你 ...

  6. 暑假每日算法学习打卡(八)----字符串,丢手绢,[SCOI2005]扫雷MINE(尺取法)【牛客】

    1.字符串 题目描述  小N现在有一个字符串S.他把这这个字符串的所有子串都挑了出来.一个S的子串T是合法的,当且仅当T中包含了所有的小写字母.小N希望知道所有的合法的S的子串中,长度最短是多少. 输 ...

  7. Codeforces 41D Pawn 简单dp

    题目链接:点击打开链接 给定n*m 的矩阵 常数k 以下一个n*m的矩阵,每一个位置由 0-9的一个整数表示 问: 从最后一行開始向上走到第一行使得路径上的和 % (k+1) == 0 每一个格子仅仅 ...

  8. hdu2067 简单dp或者记忆化搜索

    题意: 小兔的棋盘 Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  9. 第三讲 数学与简单DP【完结】

    目录 1205. 买不到的数目 [数学结论题] 1211. 蚂蚁感冒 [模拟 / 推理] 1216. 饮料换购 [简单 / 模拟] 2. 01背包问题 [板子题] 1015. 摘花生 [简单DP] 8 ...

  10. hdu 2881(简单dp)

     题意:n*n的矩阵,里面有m个格子是有任务要去完成的,t,x,y表示要在第t秒到达(x,y)的格子完成任务,问你最多可以完成多少 解题思路:简单dp,将时间排个序后就是LIS #include< ...

最新文章

  1. MATLAB机器学习系列-11:粒子群优化原理及其matlab实现
  2. 谷歌AI:根据视频生成深度图,效果堪比激光雷达
  3. 世界首富比尔盖茨花钱全过程!
  4. vue中动态指令参数
  5. 【Windows】treamview完全卸载
  6. 一文吃透strcmp函数
  7. JAVA事务配置总结
  8. 2021-02-14马克思主义概论
  9. 《JavaScript百炼成仙》 全书知识点整理
  10. 一步一步带你了解Hybrid开发框架之DsBridge
  11. 基于Cycle Spinning的移不变小波去噪
  12. SWF编辑器,替换SWF图片的工具下载
  13. 分子动力学模型的发展由来
  14. springboot热部署该怎么实现?springboot热部署实现方式
  15. 浅谈MES的通用设计之一:数据传输
  16. 台式计算机除尘方法,台式电脑主机彻底除尘经验
  17. 数据挖掘第四课(贝叶斯网络)
  18. NTLM协议中都存在那些漏洞
  19. android 音频设备类型,Android 音频
  20. Java+SSH水费管理系统(含源码+论文+答辩PPT等)

热门文章

  1. 162. Find Peak Element
  2. 【数据结构与算法】【算法思想】Dijkstra算法
  3. [Leetcode][第415题][JAVA][字符串相加][双指针]
  4. [Java]中[this][super]用法总结
  5. [Leedcode][JAVA]第[945]题
  6. Java学习笔记11-1——Spring5
  7. java如何保证类不被回收_垃圾回收机制保证了Java程序不会出现内存溢出。( )
  8. 网吧java安装路径,java环境变量配置
  9. 安装Linux后windows在哪启动,在Linux下安装windows后解决Linux不能启动能问题
  10. DM3730 LCD控制器驱动框架