【题解】NOIP2018 填数游戏
\(\text{Solution:}\)
题目标签是\(dp,\)但是纯暴力打表找规律可以有\(65\)分。
首先是对于\(O(2^{nm}*nm)\)的暴力搜索,显然都会。
考虑几条性质:
每一条由左下到右上的对角线需要非严格单调递减。
若\(a[i][j-1]=a[i-1][j]\)则以\(a[i][j]\)为左上角的矩阵填的数必须相等。
证明:
对于第一条,若不满足这条性质,则必然存在一个路径,\(R\to 1,D\to 0\)使得其不满足题意。
对于第二条,首先满足\(R\to x,D\to x,\)则对于后面的所有路径,若有一个不相等的则必然存在一条路径\(D\to Big\)或\(R\to Small\)使得题目不成立。
于是,设\(a[i][j]\)表示第\(j\)列\(i\to n\)行数字的状压结果,\(b[i][j]\)表示以\((i,j)\)为左上角的矩阵的数字是不是相等。
考虑每次填数完毕就判断一次。若矩阵相等,则\(\text{b[i][j]=b[i][j+1]&&(a[i][j+1]>>1)==a[i+1][j]}\)
然后对角线是\(\text{x<n&&y>1&&g[x][y]==g[x+1][y-1]&&!b[x+1][y](False)}\)
代码中保证只有上一次填了\(1\)下一次才能继续填。否则必须填\(0\).从而起到了剪枝的效果。
于是可以打表,继续找规律:
int A[9][9]= {
{0,0,0,0,0,0,0,0,0},
{0,2,4,8,16,32,64,128,256},
{0,0,12,36,108,324,972,2916,8748},
{0,0,0,112,336,1008,3024,9072,27216},
{0,0,0,0,912,2688,8064,24192,72576},
{0,0,0,0,0,7136,21312,63936,191808},
{0,0,0,0,0,0,56768,170112,510336},
{0,0,0,0,0,0,0,453504,1360128},
{0,0,0,0,0,0,0,0,3626752},
};
观察一下,上半个矩阵中,有很多值满足\(a[i][j]=a[i][j-1]*3.\)
所以,特判掉\(n=m\)的情况后,直接调用\(A(n,n+1)\)并使用快速幂即可。
#include<bits/stdc++.h>
using namespace std;
int n,m,R=10879488;
int A[9][9]= {
{0,0,0,0,0,0,0,0,0},
{0,2,4,8,16,32,64,128,256},
{0,0,12,36,108,324,972,2916,8748},
{0,0,0,112,336,1008,3024,9072,27216},
{0,0,0,0,912,2688,8064,24192,72576},
{0,0,0,0,0,7136,21312,63936,191808},
{0,0,0,0,0,0,56768,170112,510336},
{0,0,0,0,0,0,0,453504,1360128},
{0,0,0,0,0,0,0,0,3626752},
};
const int mod=1e9+7;
inline int add(int x,int y) {
return (x+y)%mod;
}
inline int mul(int x,int y) {
return 1ll*x*y%mod;
}
namespace P3 {
inline int qpow(int x,int y) {
int res=1;
while(y) {
if(y&1)res=mul(res,x);
x=mul(x,x);
y>>=1;
}
return res;
}
void solve() {
if(n>m)swap(n,m);
if(n==m)printf("%d\n",A[n][m]);
else {
if(n==1) {
printf("%d\n",qpow(2,m));
return;
}
int c=m-n;
if(n<8)R=A[n][n+1];
printf("%d\n",mul(R,qpow(3,c-1)));
}
}
}
namespace Biao {
int a[13][13],g[30][30],ans=0;
bool b[100][100];
bool check(int x,int y) {
a[x][y]=a[x+1][y]|(g[x][y]<<(n-x));
if(y==m)b[x][y]=1;
else b[x][y]=b[x][y+1]&&(a[x][y+1]>>1)==a[x+1][y];
if(x<n&&y>1&&g[x][y]==g[x+1][y-1]&&!b[x+1][y])return false;
return true;
}
void dfs(int x,int y) {
if(y<1) {
dfs(x-1,m);
return;
}
if(x<1) {
ans++;
return;
}
if(x==n||y==1||g[x+1][y-1]==1) {
g[x][y]=1;
if(check(x,y))dfs(x,y-1);
}
g[x][y]=0;
if(check(x,y))dfs(x,y-1);
}
void solve() {
ans=0;
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(g,0,sizeof(g));
if(n>m)swap(n,m);
dfs(n,m);R=ans;
}
}
int main() {
scanf("%d%d",&n,&m);
P3::solve();
return 0;
}
参考:https://www.luogu.com.cn/blog/2003ok/solution-p5023 Lisy_03 的博客
(侵删)
总结:数据范围小所想到的状压\(dp\)并不一定正确,在不会正解的情况下先写暴力打表。
【题解】NOIP2018 填数游戏的更多相关文章
- [Noip2018]填数游戏
传送门 Description 耳熟能详,就不多说了 Solution 对于一个不会推式子的蒟蒻,如何在考场优雅地通过此题 手玩样例,发现对于 \(n=1\) , \(ans=2^m\) .对于 \( ...
- NOIP2018 填数游戏 搜索、DP
LOJ 感觉这个题十分好玩于是诈尸更博.一年之前的做题心得只有这道题还记得清楚-- 设输入为\(n,m\)时的答案为\(f(n,m)\),首先\(f(n,m)=f(m,n)\)所以接下来默认\(n \ ...
- 【比赛】NOIP2018 填数游戏
打表找规律.... #include<bits/stdc++.h> #define ui unsigned int #define ll long long #define db doub ...
- @NOIP2018 - D2T2@ 填数游戏
目录 @题目描述@ @题解@ @代码@ @题目描述@ 小 D 特别喜欢玩游戏.这一天,他在玩一款填数游戏. 这个填数游戏的棋盘是一个 n×m 的矩形表格.玩家需要在表格的每个格子中填入一个数字(数字 ...
- 【逆向笔记】2017年全国大学生信息安全竞赛 Reverse 填数游戏
2017年全国大学生信息安全竞赛 Reverse 填数游戏 起因是吾爱破解大手发的解题思路,觉得题挺有意思的,就找来学习学习 这是i春秋的下载链接 http://static2.ichunqiu.co ...
- luogu P5023 填数游戏
luogu loj 被这道题送退役了 题是挺有趣的,然而可能讨论比较麻烦,肝了2h 又自闭了,鉴于CSP在即,就只能先写个打表题解了 下面令\(n<m\),首先\(n=1\)时答案为\(2^m\ ...
- UOJ#440. 【NOIP2018】填数游戏 动态规划
原文链接www.cnblogs.com/zhouzhendong/p/UOJ440.html 前言 菜鸡选手到省选了才做联赛题. 题解 首先我们分析一下性质: 1. 假如一个格子是 0,那么它的右上角 ...
- [NOIP2018 TG D2T2]填数游戏
题目大意:$NOIP2018\;TG\;D2T2$ 题解:在skip2004的博客基础上修改的,也是暴搜. 说明一下把vector改成数组并不可以通过此题,记录. 结论:在$m>n+1$时答案为 ...
- JZOJ5965【NOIP2018提高组D2T2】填数游戏
题目 作为NOIP2018的题目,我觉得不需要把题目贴出来了. 大意就是,在一个n∗mn*mn∗m的010101矩阵中,从左上角到右下角的路径中,对于任意的两条,上面的那条小于下面的那条.问满足这样的 ...
随机推荐
- HDU - 6570 - Wave(暴力)
Avin is studying series. A series is called "wave" if the following conditions are satisfi ...
- 2020年的UWP——通过Radio类控制Cellular(1)
最近在做UWP的项目,在2020年相信这已经是相对小众的技术了,但是在学习的过程中,发现某软这么几年仍然添加了不少的API,开放了相当多的权限.所以打算总结一下最近的一些经验和收获,介绍一下2020年 ...
- [Python]打印指定目录下所有子目录
import os for root,dirs,files in os.walk(r"/home/os-hy01"): for dir in dirs: print(dir) -- ...
- 解决Maven下载速度缓慢问题
解决Maven下载速度缓慢问题 第一步:找到自己安装maven的路径,选择setting.xml D:\apache-maven-3.2.2\conf\settings.xml 第二步:打开setti ...
- linux系统jdk安装
1.软件包下载:官网 http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html下载linu ...
- @RequestBody使用说明
@RequestBody 使用 @RequestBody这个对于一般刚接触来说,确实有点陌生,但是现在前端,后端技术分的太细,越来越多的技术层出不穷,前端就分化出POST ,GET,PUT,DELET ...
- 你准备好开始DevOps了吗?
前面一章节我们已经了解了Agile,CI/CD,DevOps,作为DevOps的起点,对于一个团队,如何开始自己的持续集成?根据我的经验,列出了一下需要考虑的点 1. 代码管理/分支策略 代码托管在哪 ...
- 再不迁移到Material Design Components 就out啦
翻译自国外文档加自己理解 原文 我们最近宣布了 Material Design Components(MDC)1.1.0 ,这是一个库更新,为您的 Android 应用程序带来了 Material T ...
- docker之windows安装¢OS安装
按这个安装 没什么毛病 https://blog.csdn.net/vitaair/article/details/80894890 https://www.runoob.com/docker/ce ...
- JAVA之代理1JDK
代理主要有JDK的代理以及CGLIB的代理 代理方式 实现 优点 缺点 特点 JDK静态代理 代理类与委托类实现同一接口,并且在代理类中需要硬编码接口 实现简单,容易理解 代理类需要硬编码接口,在实际 ...