「模拟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 条边的无向连通图),由于新建的办公室太大以 ...
随机推荐
- STL实现的底层数据结构简介
STL实现的底层数据结构简介 C++ STL 的实现: 1.vector 底层数据结构为数组 ,支持快速随机访问 2.list 底层数据结构为双向链表,支持快速增删 3.deque 底层数 ...
- OCR-Form-Tools项目试玩记录(二)产品评测
这是一篇软工课程作业博客 项目 内容 这个作业属于哪个课程 北航2020春软件工程 006班(罗杰.任健 周五) 这个作业的要求在哪里 个人博客作业-软件案例分析 个人课程目标 系统地学习软件工程理论 ...
- BUAAOO第四单元总结与学期回顾
第四单元架构设计 第四单元要完成的是对给定UML元素的建模/统计/分析,考虑到UML元素的组织是树状的,很容易想到基于树状的数据结构完成 由于UML元素已经由官方接口给出,因此结点类采用wrapper ...
- 【BUAA软工】团队任务拆解
项目 内容 班级:北航2020春软件工程 博客园班级博客 作业:团队任务拆解及时间规划 团队任务拆解 Alpha阶段总体规划 初步完成产品功能规格说明书中的基础功能 目前阶段仅支持本地上传文件至当前N ...
- 【vue2】(一)基础使用
[vue2](一)基础使用 MVVM MVVM: View - Model - ViewModel View: Dom层,视图层 Model: Plain JavaScript Objects,数据层 ...
- Arduino杀手在此!!ESP 8266 NodeMCU小白手把手入门(二)(解惑篇)
上一次更新主要是简单介绍了NodeMCU的基本知识并且进行了一次简单的实操演示,最近有一些读者向我提出了一些小问题,所以决定出一期解惑篇,主要针对的是基础知识不是太牢固,或是喜欢刨根问底的小可爱们.里 ...
- .NET平台系列10 .NET统一平台愿景
系列目录 [已更新最新开发文章,点击查看详细] 2019年,微软分享了[统一的.NET堆栈和生态系统的愿景].给开发者带来的价值是,将能够使用一组API,语言和工具来针对广泛的应用程序类型,包 ...
- [Java]数据分析--聚类
距离度量 需求:计算两点间的欧几里得距离.曼哈顿距离.切比雪夫距离.堪培拉距离 实现:利用commons.math3库相应函数 1 import org.apache.commons.math3.ml ...
- ruby基础(三)
类和模块 1.类 类是面向对象中一个重要的术语.我们可以把类看作是对象的抽象, 所有的这类对象都有这些特征.而对象则是类的具体实现,按照类的要求创建的 对象就是该类的对象.类就像对象的雏形一样,决定了 ...
- Prometheus存储原理及数据备份还原
prometheus将采集到的样本以时间序列的方式保存在内存(TSDB 时序数据库)中,并定时保存到硬盘中.与zabbix不同,zabbix会保存所有的数据,而prometheus本地存储会保存15天 ...