「模拟8.23」阴阳 DP
对于此题的性质我们考虑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的更多相关文章
- 「模拟8.23」one递推,约瑟夫
前置芝士约瑟夫问题 这样大概就是板子问题了 考场的树状数组+二分的60分暴力??? 1 #include<bits/stdc++.h> 2 #define int long long 3 ...
- 「模拟赛20190327」 第二题 DP+决策单调性优化
题目描述 小火车虽然很穷,但是他还是得送礼物给妹子,所以他前往了二次元寻找不需要钱的礼物. 小火车准备玩玩二次元的游戏,游戏当然是在一个二维网格中展开的,网格大小是\(n\times m\)的,某些格 ...
- 「模拟赛20181025」御风剑术 博弈论+DP简单优化
题目描述 Yasuo 和Riven对一排\(n\)个假人开始练习.斩杀第\(i\)个假人会得到\(c_i\)个精粹.双方轮流出招,他们在练习中互相学习,所以他们的剑术越来越强.基于对方上一次斩杀的假人 ...
- 「模拟赛20191019」B 容斥原理+DP计数
题目描述 将\(n\times n\)的网格黑白染色,使得不存在任意一行.任意一列.任意一条大对角线的所有格子同色,求方案数对\(998244353\)取模的结果. 输入 一行一个整数\(n\). 输 ...
- 「模拟赛20191019」A 简单DP
题目描述 给一个\(n\times m\)的网格,每个格子上有一个小写字母. 对于所有从左上角\((1,1)\)到右下角\((n,m)\)只向下或向右走的路径构成的集合,判断是否存在两条走法不同的路径 ...
- 「模拟8.21」山洞(矩阵优化DP)
暴力: 正解: 考虑循环矩阵,f[i][j]表示从i点到j点的方案数 我们发现n很小,我们预处理出n次的f[i][j] 然后在矩阵快速幂中,我们要从当前的f[i][j]*f[j][k]-->fi ...
- 2021升级版微服务教程5—通过IDEA运行多个项目实例「模拟集群」
2021升级版SpringCloud教程从入门到实战精通「H版&alibaba&链路追踪&日志&事务&锁」 教程全目录「含视频」:https://gitee.c ...
- 「模拟赛20180306」回忆树 memory LCA+KMP+AC自动机+树状数组
题目描述 回忆树是一棵树,树边上有小写字母. 一次回忆是这样的:你想起过往,触及心底--唔,不对,我们要说题目. 这题中我们认为回忆是这样的:给定 \(2\) 个点 \(u,v\) (\(u\) 可能 ...
- 「模拟赛 2018-11-02」T3 老大 解题报告
老大 题目描述 因为 OB 今年拿下 4 块金牌,学校赞助扩建劳模办公室为劳模办公室群,为了体现 OI 的特色,办公室群被设计成了树形(n 个点 n − 1 条边的无向连通图),由于新建的办公室太大以 ...
随机推荐
- Windows进程间通讯(IPC)----信号量
线程同步内核对象 操作系统进行进程间同步是利用信号量机制.对于windows系统而言,可以利用一些内核对象进行线程同步,因为这些内核对象可以命名并且属于系统内核,所以可以支持不同进程间的线程同步进而实 ...
- Iterable 和 Iterator
可以被for循环输出的为iterable (可迭代对象) 可以被next()调用并不断返回下一个数据的对象为iterator迭代器(python一切皆对象) 数据流,无法知晓其终点,只能推过next不 ...
- Java安全之Filter权限绕过
Java安全之Filter权限绕过 0x00 前言 在一些需要挖掘一些无条件RCE中,大部分类似于一些系统大部分地方都做了权限控制的,而这时候想要利用权限绕过就显得格外重要.在此来学习一波权限绕过的思 ...
- Envoy:主动健康监测
实验文件 docker-compose version: '3' services: envoy: image: envoyproxy/envoy-alpine:v1.15-latest enviro ...
- Canal和Otter讨论二(原理与实践)
上次留下的问题 问题一: 跨公网部署Otter 参考架构图 解析 a. 数据涉及网络传输,S/E/T/L几个阶段会分散在2个或者更多Node节点上,多个Node之间通过zookeeper进行协同工 ...
- Microk8s 安装helm3
Microk8s 安装helm3 原本使用官方的命令时这样的.但是使用的是官方的源,网络极不稳定.就出现了下面的状况.解决方法是更改为国内的源. microk8s enable helm3 curl: ...
- 使用 parted 命令可以查看系统采用什么类型的分区表 gpt/mbr/msdos/ext/ext/ext2/ext3/ext4
Linux磁盘表示方式 Linux以字母标识磁盘的个数 a:第一块 b:第二块 Linux用数字标识分区:1-4标识主分区或扩展分区 逻辑分区从5开始 例如:sda.sda1.sda2 低级格式化 ...
- IDEA workspace.xml 在 git 中无法忽略 ignore 问题
问题描述 关于 .idea 的文件夹中的 workspace.xml 设置 ignore 之后每次 commit 依旧提示需要提交改变,这就会导致, 每次merge就会导致提示"本地文件改变 ...
- linux 创建网桥
由于最近项目需验证个问题,需求是要创建一个虚拟机网桥,在使用ifconfig命令查看时让docker0网桥不在第一个显示,因此,我们创建一个虚拟网桥让它排在第一位置 项目使用Centos7系统,因此使 ...
- python文件处理(对比和筛选)
#!/user/bin/python #!coding=utf-8 # -*- coding: utf-8 -*- # 2017-9-25 #author:jingwenshuai import sy ...