对于此题的性质我们考虑DP

分四种情况

黑色块在右侧单调降,单调升

还有在左侧

另外我们这样可能会记重,所以还要将重复记过的也就是边界线是横的和竖的

然后还要将全白全黑加上

  1 #include<bits/stdc++.h>
2 #define MAXN 2100
3 #define int long long
4 using namespace std;
5 int f[5][MAXN][MAXN];
6 int sum[5][MAXN][MAXN];
7 int n,m;
8 const int mod=1e9+7;
9 char c[MAXN][MAXN];
10 int jud[2][MAXN][MAXN];
11 int jud_sum[2][MAXN][MAXN];
12 void work(int k,int cal)
13 {
14 f[k][0][m]=1;
15 for(int i=1;i<=n;++i)//黑色单降靠左
16 {
17 sum[k][i-1][m]=f[k][i-1][m];
18 for(int j=m-1;j>=0;--j)
19 {
20 sum[k][i-1][j]=(sum[k][i-1][j+1]+f[k][i-1][j])%mod;
21 //printf("sum[%lld][%lld][%lld]=%lld\n",k,i-1,j,sum[k][i-1][j]);
22 }
23 for(int j=0;j<=m;++j)
24 {
25 //printf("i%lld j=%lld jud%lld %lld\n",i,j,jud[cal][i][j],(jud[cal^1][i][m]-jud[cal^1][i][j]));
26 if(j!=0)
27 if(jud[cal][i][j]!=0||(jud[cal^1][i][m]-jud[cal^1][i][j])!=0){continue;}
28 if(j==0)
29 if(jud[cal][i][j]||jud[cal^1][i][m]){continue;}
30 f[k][i][j]=sum[k][i-1][j]%mod;
31 //printf("f[%lld][%lld][%lld]=%lld\n",k,i,j,f[k][i][j]);
32 }
33 }
34 f[k+1][0][0]=1;
35 for(int i=1;i<=n;++i)//黑色单升靠左
36 {
37 sum[k+1][i-1][0]=f[k+1][i-1][0];
38 for(int j=1;j<=m;++j)
39 {
40 sum[k+1][i-1][j]=(sum[k+1][i-1][j-1]+f[k+1][i-1][j])%mod;
41 }
42 for(int j=0;j<=m;++j)
43 {
44 if(j)
45 if(jud[cal][i][j]||(jud[cal^1][i][m]-jud[cal^1][i][j]))continue;
46 if(j==0)
47 if(jud[cal][i][j]||jud[cal^1][i][m])continue;
48 f[k+1][i][j]=sum[k+1][i-1][j]%mod;
49 //printf("f[%lld][%lld][%lld]=%lld\n",k+1,i,j,f[k+1][i][j]);
50 }
51 }
52 }
53 int ans=0;
54 int get_sum(int k,int x1,int y1,int x2,int y2)
55 {
56 if(x1>x2)return 0;if(y1>y2)return 0;
57 return (jud_sum[k][x2][y2]-jud_sum[k][x1-1][y2]-jud_sum[k][x2][y1-1]+jud_sum[k][x1-1][y1-1]+mod)%mod;
58 }
59 void work2()
60 {
61 for(int i=0;i<=n;++i)
62 {
63 if(get_sum(1,1,1,i,m)==0&&get_sum(0,i+1,1,n,m)==0)
64 {
65 ans--;
66 }
67 }
68 for(int i=0;i<=n;++i)
69 {
70 if(get_sum(0,1,1,i,m)==0&&get_sum(1,i+1,1,n,m)==0)
71 {
72 ans--;
73 }
74 }
75 for(int i=0;i<=m;++i)
76 {
77 if(get_sum(0,1,1,n,i)==0&&get_sum(1,1,i+1,n,m)==0)
78 {
79 ans--;
80 }
81 }
82 for(int i=0;i<=m;++i)
83 {
84 if(get_sum(1,1,1,n,i)==0&&get_sum(0,1,i+1,n,m)==0)
85 {
86 ans--;
87 }
88 }
89 if(get_sum(1,1,1,n,m)==0)ans++;
90 if(get_sum(0,1,1,n,m)==0)ans++;
91 }
92 signed main()
93 {
94 scanf("%lld%lld",&n,&m);
95 for(int i=1;i<=n;++i)
96 {
97 scanf("%s",c[i]+1);
98 for(int j=1;j<=m;++j)
99 {
100 jud[0][i][j]+=jud[0][i][j-1];
101 jud[1][i][j]+=jud[1][i][j-1];
102 jud_sum[0][i][j]=(jud_sum[0][i-1][j]+jud_sum[0][i][j-1]-jud_sum[0][i-1][j-1])%mod;
103 jud_sum[1][i][j]=(jud_sum[1][i-1][j]+jud_sum[1][i][j-1]-jud_sum[1][i-1][j-1])%mod;
104 if(c[i][j]=='B'){jud[0][i][j]++;jud_sum[0][i][j]++;}
105 if(c[i][j]=='W'){jud[1][i][j]++;jud_sum[1][i][j]++;}
106 }
107 }
108 work(1,1);
109 work(3,0);
110 for(int k=1;k<=4;++k)
111 {
112 for(int i=0;i<=m;++i)
113 {
114 ans=(ans+f[k][n][i])%mod;
115 //printf("f[%lld][%lld][%lld]=%lld\n",k,n,i,f[k][n][i]);
116 }
117 }
118 //printf("初ans=%lld\n",ans);
119 work2();
120 printf("%lld\n",ans%mod);
121 }

「模拟8.23」阴阳 DP的更多相关文章

  1. 「模拟8.23」one递推,约瑟夫

    前置芝士约瑟夫问题 这样大概就是板子问题了 考场的树状数组+二分的60分暴力??? 1 #include<bits/stdc++.h> 2 #define int long long 3 ...

  2. 「模拟赛20190327」 第二题 DP+决策单调性优化

    题目描述 小火车虽然很穷,但是他还是得送礼物给妹子,所以他前往了二次元寻找不需要钱的礼物. 小火车准备玩玩二次元的游戏,游戏当然是在一个二维网格中展开的,网格大小是\(n\times m\)的,某些格 ...

  3. 「模拟赛20181025」御风剑术 博弈论+DP简单优化

    题目描述 Yasuo 和Riven对一排\(n\)个假人开始练习.斩杀第\(i\)个假人会得到\(c_i\)个精粹.双方轮流出招,他们在练习中互相学习,所以他们的剑术越来越强.基于对方上一次斩杀的假人 ...

  4. 「模拟赛20191019」B 容斥原理+DP计数

    题目描述 将\(n\times n\)的网格黑白染色,使得不存在任意一行.任意一列.任意一条大对角线的所有格子同色,求方案数对\(998244353\)取模的结果. 输入 一行一个整数\(n\). 输 ...

  5. 「模拟赛20191019」A 简单DP

    题目描述 给一个\(n\times m\)的网格,每个格子上有一个小写字母. 对于所有从左上角\((1,1)\)到右下角\((n,m)\)只向下或向右走的路径构成的集合,判断是否存在两条走法不同的路径 ...

  6. 「模拟8.21」山洞(矩阵优化DP)

    暴力: 正解: 考虑循环矩阵,f[i][j]表示从i点到j点的方案数 我们发现n很小,我们预处理出n次的f[i][j] 然后在矩阵快速幂中,我们要从当前的f[i][j]*f[j][k]-->fi ...

  7. 2021升级版微服务教程5—通过IDEA运行多个项目实例「模拟集群」

    2021升级版SpringCloud教程从入门到实战精通「H版&alibaba&链路追踪&日志&事务&锁」 教程全目录「含视频」:https://gitee.c ...

  8. 「模拟赛20180306」回忆树 memory LCA+KMP+AC自动机+树状数组

    题目描述 回忆树是一棵树,树边上有小写字母. 一次回忆是这样的:你想起过往,触及心底--唔,不对,我们要说题目. 这题中我们认为回忆是这样的:给定 \(2\) 个点 \(u,v\) (\(u\) 可能 ...

  9. 「模拟赛 2018-11-02」T3 老大 解题报告

    老大 题目描述 因为 OB 今年拿下 4 块金牌,学校赞助扩建劳模办公室为劳模办公室群,为了体现 OI 的特色,办公室群被设计成了树形(n 个点 n − 1 条边的无向连通图),由于新建的办公室太大以 ...

随机推荐

  1. Visual Lab Online —— 事后分析

    项目 内容 班级:北航2020春软件工程 博客园班级博客 作业:事后分析 事后分析 设想和目标 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 我们的软件使得编写简 ...

  2. Spring事务明明开启了,为什么没起作用???

    一.事务的特性(ACID) 1.原子性(Atomicity):事务是一个原子操作,由一系列动作组成.事务的原子性确保动作要么全部完成,要么完全不起作用. 2.一致性(Consistency):执行事务 ...

  3. [c++] 分号的使用

    加分号的情况: 语句结束加分号(否则编译器不知道在哪里结束语句,编译器不识别换行,写代码时换行和退格只是为了看着舒服,但本质上代码是写给编译器看的) 声明语句后加分号(也是一种语句) 结构体.类定义后 ...

  4. Linux查看PCIe版本及速率# lspci -vvv |grep Width -i

    Linux查看PCIe版本及速率 https://www.cnblogs.com/lsgxeva/p/9542975.html# lspci -vvv |grep Width -i # lspci | ...

  5. Linux_搭建Samba服务(认证访问)

    [RHEL8]-SMBserver:[RHEL7]-SMBclient !!!测试环境我们首关闭防火墙和selinux(SMBserver和SMBclient都需要) [root@localhost ...

  6. systemd 进程管理详解

    systemd进程管理 systemd管理的优势 1.最新系统都采用systemd管理(RedHat7,CentOS7,Ubuntu15...) 2.CentOS7 支持开机并行启动服务,显著提高开机 ...

  7. cnetos 网卡绑定 eth0+eth1做双网卡绑定到bond0

    1.网卡绑定:eth0+eth1做双网卡绑定到bond0 二.网络配置 网卡绑定1./etc/sysconfig/network-scripts/目录下建立ifcfg-bond0文件,内容如下DEVI ...

  8. 在Linux服务器,搭建K8s服务【脚本篇】

    前言 好久没有写博客了,本文主要是对网上文章的总结篇,主要是将安装和运行代码做了一次真机实验,亲测可用.文章内包含的脚本和代码,多来自于网络,也有我自己的调整和配置,文章末尾对参考的文献做了列举,方便 ...

  9. 『动善时』JMeter基础 — 25、JMeter参数化补充练习

    目录 1.使用"CSV数据文件设置"组件实现参数化 (1)测试计划中的元件 (2)数据文件内容 (3)线程组元件内容 (4)HTTP信息头管理器组件内容 (5)CSV数据文件设置组 ...

  10. [算法] 数据结构 splay(伸展树)解析

    前言 splay学了已经很久了,只不过一直没有总结,鸽了好久来写一篇总结. 先介绍 splay:亦称伸展树,为二叉搜索树的一种,部分操作能在 \(O( \log n)\) 内完成,如插入.查找.删除. ...