@填数游戏@

  • @题目描述@
  • @题解@
  • @代码@
  • @end@

@题目描述@

小 D 特别喜欢玩游戏。这一天,他在玩一款填数游戏。
这个填数游戏的棋盘是一个 n×m 的矩形表格。玩家需要在表格的每个格子中填入一个数字(数字 0 或者数字 1 ),填数时需要满足一些限制。

下面我们来具体描述这些限制。

为了方便描述,我们先给出一些定义:
我们用每个格子的行列坐标来表示一个格子,即(行坐标,列坐标)。(注意: 行列坐标均从 0 开始编号)
一条路径是合法的当且仅当:
(1)这条路径从矩形表格的左上角的格子(0,0)出发,到矩形的右下角格子 (n−1,m−1)结束;
(2)在这条路径中,每次只能从当前的格子移动到右边与它相邻的格子,或者 从当前格子移动到下面与它相邻的格子。

对于一条合法的路径 P,我们可以用一个字符串 w(P) 来表示,该字符串的长度为 n+m−2,其中只包含字符“R”或者字符“D”, 第 i 个字符记录了路径 P 中第 i 步的移动 方法,“ R”表示移动到当前格子右边与它相邻的格子,“ D”表示移动到当前格子下面 与它相邻的格子。

同时,将每条合法路径 P 经过的每个格子上填入的数字依次连接后,会得到一个长 度为 n+m−1 的 01 字符串,记为 s(P) 。

游戏要求小 D 找到一种填数字 0、 1 的方法,使得对于两条路径P1,P2,如果w(P1) > w(P2),那么必须s(P1) ≤ s(P2)。

但是仅仅是找一种方法无法满 足小 D 的好奇心,小 D 更想知道这个游戏有多少种玩法,也就是说,有多少种填数字 的方法满足游戏的要求?

小 D 能力有限,希望你帮助他解决这个问题,即有多少种填 0、1 的方法能满足题目要求。由于答案可能很大,你需要输出答案对 10^9 + 7 取模的结果。

输入
输入共一行,包含两个正整数 n,m,由一个空格分隔,表示矩形的大小。其中 n 表示矩形表格的行数,m 表示矩形表格的列数。

输出
输出共一行,包含一个正整数,表示有多少种填 0、1 的方法能满足游戏的要求。 注意:输出答案对 10^9+7 取模的结果。

输入样例#1
2 2
输出样例#1
12

输入样例#2
3 3
输出样例#2
112

输入样例#3
5 5
输出样例#3
7136

数据规模与约定
n<=8,m<=10^6。

@题解@

傻逼规律题,我竟然不会做。
我太弱了……

题目中的限制等价于:对于所有的点,如图示的红色路径的数字串要 ≥ 蓝色路径的数字串。

我们再把这个限制进行转换:
(1)每一条自右上至左下的对角线的数字总是先出现一堆 0,再出现一堆 1。
(2)如果 (a, b+1) = (a+1, b),则以(a+1, b+1)为左上角,以(n-1, m-1)为右下角的矩形,每一条自右上至左下的对角线的数字全部相同。

可以证明以上的转换都是等价的。


然后就会发现一件很有意思的事情:对于这条对角线 2,肯定是000,001,011,111。这条对角线上一定有 2 个元素相同,也就说限制(2)会限制掉很大一个区域!

于是我们就可以根据这个设计算法了:

先手推 n = 1,n = 2, n = 3 的情况,将它们特判掉。
当 n = 1 时,ans = 2m
当 n = 2 时,ans = 4*3m-1
当 n = 3 时,ans = 112*3m-3

然后:如果交换 n 和 m ,答案不会变。所以我们不妨假设 n <= m。

计算出上图中对角线 1 为 00, 11 的方案数。除此之外对角线 1 一定为 01。
对于对角线 2,先考虑它为 000,111 的情况,然后考虑它为 001,011 的情况。

接下来考虑如何具体计数。
假如对角线 1 为 00, 11:

将剩余的对角线分为三类:两个端点没有被限制(形如 1),对答案的贡献为 4;两个端点被限制了一个(形如 2),对答案的贡献为 3;两个端点都被限制(形如 3),对答案的贡献为 2。将所有对角线的贡献乘起来即可。可以用快速幂。

假如对角线 2 为 000, 111:

图中所标出的对角线是不受限制的。蓝色限制与紫色限制相互组合,可以发现和上面那种情况是差不大多的(除了边缘的行列都被限制)。因此,依然还是按照上文所提到的方法进行计数。

假如对角线 2 为 001,011。因为是对称的,我们只需要弄清 001 的求解方式即可类比推导出 011 的求解方法。

紫色是限制区域。如果绿色矩形中有一个对角线相同,则限制区域会如下图所示。

对比上面那种情况,我们只是将蓝色矩形往下平移了一点。具体的计数方式还是跟上面那种情况是一样的。
还要讨论绿色矩形内对角线都互不相同的方案数。

注意要分类讨论 n = m 和 n < m 的 情况。

@代码@

我觉得我的题解可能描述的不是很具体……因为把这道题解释清楚是一件对我来说不太容易的事情……但是我觉得关键的地方我都写上了。
还是请大家多多见谅啦,如果有疑问就留言提出来吧,我会尽力解答的。

#include<cstdio>
#include<algorithm>
using namespace std;
const int MOD = int(1E9) + 7;
int pow_mod(int b, int p) {int ret = 1;while( p ) {if( p & 1 ) ret = 1LL*ret*b%MOD;b = 1LL*b*b%MOD;p >>= 1;}return ret;
}
int main() {int n, m;scanf("%d%d", &n, &m);if( n > m ) swap(n, m);if( n == 1 ) {printf("%d\n", pow_mod(2, m));return 0;}else if( n == 2 ) {printf("%lld\n", 4LL*pow_mod(3, m-1)%MOD);return 0;}else if( n == 3 ) {printf("%lld\n", 112LL*pow_mod(3, m-n)%MOD);return 0;}else {int ans = 0;if( n == m ) {ans = (ans + 2LL*pow_mod(4, n-2)%MOD*pow_mod(2, n-1)%MOD)%MOD;ans = (ans + 2LL*5LL*pow_mod(4, n-4)%MOD*pow_mod(2, n-1)%MOD)%MOD;for(int i=4;i<=m;i++) {if( i == m ) ans = (ans + 4LL*3LL*pow_mod(2, n-2)%MOD)%MOD;else ans = (ans + 4LL*5LL*pow_mod(4, n-i-1)%MOD*pow_mod(2, n-1)%MOD)%MOD;}ans = (ans + 3LL*pow_mod(2, n-2))%MOD;for(int i=4;i<=n;i++) {if( i == n ) ans = (ans + 4LL*3LL*pow_mod(2, m-2)%MOD)%MOD;else ans = (ans + 4LL*5LL*pow_mod(4, m-i-1)%MOD*pow_mod(2, m-1)%MOD)%MOD;}ans = (ans + 3LL*pow_mod(2, n-2))%MOD;}else {ans = (ans + 2LL*pow_mod(4, n-2)%MOD*pow_mod(3, m-n)%MOD*pow_mod(2, n-1)%MOD)%MOD;ans = (ans + 2LL*5LL*pow_mod(4, n-4)%MOD*pow_mod(3, m-n)%MOD*pow_mod(2, n-1)%MOD)%MOD;for(int i=4;i<=m;i++) {if( i == m ) ans = (ans + 3LL*3LL*pow_mod(2, n-2)%MOD)%MOD;else if( i > n ) ans = (ans + 3LL*4LL*pow_mod(3, m-i-1)%MOD*pow_mod(2, n-1)%MOD)%MOD;else if( i == n ) ans = (ans + 4LL*4LL*pow_mod(3, m-n-1)%MOD*pow_mod(2, n-1)%MOD)%MOD;else if( i < n ) ans = (ans + 4LL*5LL*pow_mod(4, n-i-1)%MOD*pow_mod(3, m-n)%MOD*pow_mod(2, n-1)%MOD)%MOD;}ans = (ans + 3LL*pow_mod(2, n-2))%MOD;for(int i=4;i<=n;i++) {if( i == n ) ans = (ans + 4LL*4LL*pow_mod(3, m-n-1)%MOD*pow_mod(2, n-1)%MOD)%MOD;else ans = (ans + 4LL*5LL*pow_mod(4, n-i-1)%MOD*pow_mod(3, m-n)%MOD*pow_mod(2, n-1)%MOD)%MOD;}ans = (ans + 4LL*pow_mod(3, m-n-1)%MOD*pow_mod(2, n-1)%MOD)%MOD;}printf("%d\n", 2LL*ans%MOD);//*2:左上角的填数方式}
}

@end@

就是这样,新的一天里,也请多多关照哦(ノω<。)ノ))☆.。

【NOIP2018】D2T2 填数游戏相关推荐

  1. #535. 「NOIP2018」填数游戏

    代码: #include<cstdio> #include<cstring> #include<algorithm> #define P 1000000007 us ...

  2. 【NOIP2018提高组D2T2】填数游戏

    前言--2020.10.17 下面的公式推导似乎有些出锅,具体情况就看图想想. Description 小D特别喜欢玩游戏.这一天,他在玩一款填数游戏. 这个填数游戏的棋盘是一个n*m的矩形表格.玩家 ...

  3. 【NOIP2018】DAY2T2——填数游戏(轮廓线状压的dp?搜索打表)

    描述 小 D 特别喜欢玩游戏.这一天,他在玩一款填数游戏. 这个填数游戏的棋盘是一个n × m的矩形表格.玩家需要在表格的每个格子中填入一个数字(数字 0 或者数字 1),填数时需要满足一些限制. 下 ...

  4. 2018D2T2 P5023 填数游戏

    P5023 填数游戏 https://www.luogu.com.cn/problem/P5023 解题参考: https://www.acwing.com/activity/content/code ...

  5. 枚举算法5——填数游戏

    填数游戏,如图所示每个汉字代表一个数字,不同的汉字代表数字不同,要求填写这些汉字代表的数字. [分析] 从图中可以看出,共有5个汉字,每个汉字是数字0~9中的一个.显然"北"和&q ...

  6. P5023 填数游戏

    题目描述 小 D 特别喜欢玩游戏.这一天,他在玩一款填数游戏. 这个填数游戏的棋盘是一个n×m的矩形表格.玩家需要在表格的每个格子中填入 一个数字(数字 0或者数字 1),填数时需要满足一些限制. 下 ...

  7. 1908: 【18NOIP提高组】填数游戏

    [题目描述] 小 D 特别喜欢玩游戏.这一天,他在玩一款填数游戏. 这个填数游戏的棋盘是一个n×mn×m的矩形表格.玩家需要在表格的每个格子中填入一个数字(数字 00 或者数字 11),填数时需要满足 ...

  8. 170713 逆向-填数游戏

    1625-5 王子昂 总结<2017年7月13日> [连续第284天总结] A. CISCN 结合WP再战RE B. 这么久之后完整的wp终于出来了,回过头再做一遍之前的re 首先是最早放 ...

  9. 【NOIP 2018 提高组】填数游戏

    传送门 problem 小 D 特别喜欢玩游戏.这一天,他在玩一款填数游戏. 这个填数游戏的棋盘是一个 n×mn \times mn×m 的矩形表格.玩家需要在表格的每个格子中填入一个数字(数字 00 ...

最新文章

  1. 五年循环期限已到,我们又要步入“AI寒冬”了吗?
  2. N个三角形分割平面个数(数学)
  3. java 内嵌调用_Java高级开发必会的50个性能优化的细节(珍藏版)
  4. 【操作系统】中断和异常的比较
  5. display none的元素重新展示如何撑开页面_寻根问底之——元素隐藏你知多少?
  6. Hibernate 注解 没有加@Column一样会在数据库创建这些字段
  7. vb与数据库(一)之迟到的耿建玲视频总结
  8. eclipse中maven项目pom文件第一行报错解决方法
  9. Atitit webservice发现机制 WS-Discovery标准的规范attilax总结
  10. java.lang.NoClassDefFoundError: com/baidu/ueditor/ActionEnter报错解决
  11. JAVA小白 编程练习500题 超详细!!!带答案!!!持续更新中~
  12. linux安装工具的过程
  13. PS将红底证件照改为白底
  14. 比较详细的一份Google hacking语法 Google黑客
  15. linux的QQ安装在哪个文件夹,linux安装QQ
  16. 如何利用COOC生成动态排名变化利器可识别的数据格式
  17. VUE 中 keep-alive 的 --是什么-- 使用场景-- 作用-- 新增属性--动态组件--理解
  18. 神经网络芯片概念股,图神经网络预测股票
  19. cad套索选择lisp_怎么将CAD2015,CAD2016的窗交窗口选择框的套索改为矩形吗
  20. Win7系统更改桌面文件路径的详细步骤

热门文章

  1. 极光短信验证码的集成过程
  2. python字符串的内部函数_「Python」字符串操作内置函数
  3. 视频教程-微信公众号实战(Java版本,带前后台)-微信开发
  4. 数学建模学习(7):分支结构与循环结构详解
  5. 如何构建VoIP来是实现电话诈骗之——Asterisk的设置
  6. js简单插件(饼形图)
  7. [禅悟人生]学习是一种偏执
  8. 问题解决:ERROR: Cannot uninstall 'llvmlite'.
  9. body onload
  10. 尚硅谷智慧校园-SpringBoot最佳入手级项目