NOIP提高组【JZOJ4787】数格子
来源:互联网 发布:知乎 南北战争的武器 编辑:程序博客网 时间:2024/05/20 02:29
Description
Data Constraint
每个测试点数据组数不超过10组
Solution
这是道简单的状态压缩dp。我们设出f[i][j]表示现在做到第i行,第i行的状态为j的方案数。第k位为1表示这里放了一块打竖的牌,这个牌的最上一行为k,第k位为0表示这里它的一行同一个地方放了个打竖的牌,或者这一行放了个打横的牌。显然f[i][j]可由f[i-1][k]转移过来。前提是若k的第x位为1,那么j的这一位必须为0;若k的第x位为0,则不对j作要求。但除了j必须为0的位置以外,其他位要想为0必须为相邻的两个同时为0(考虑到列数只有4,一行最多只有两个打横的牌)。这样我们就做出60分。
我们发现每次有第i行转移到第i+1行,和第i+1行转移到第i+2行的转移方向是一样的,即在第i行状态j可以转移到第i+1行状态k,那么第i+1行状态j可以转移到第i+2行状态k。所以我们用16*16的矩阵记录下每个状态可以转移到那些状态,用矩阵快速幂即可。时间复杂度O(logN∗212 )。
代码
#include<iostream>#include<cstring>#include<cstdio>#include<cmath>#include<algorithm>#define ll long longusing namespace std;const int maxn=10,maxn1=20;int f[maxn][maxn1],n,m,i,t,j,k,l,p,p1;struct code{ ll a[maxn1][maxn1];}a,b;code c(code x,code y){ int i,j,k;code z; memset(z.a,0,sizeof(z.a)); for (i=0;i<=15;i++) for (j=0;j<=15;j++) for (k=0;k<=15;k++) z.a[i][j]=(z.a[i][j]+x.a[i][k]*y.a[k][j]%m)%m; return z;}code mi(int x){ if (x==1) return a; code t=mi(x/2); if (x%2) return c(c(t,t),a);return c(t,t);}int main(){// freopen("data.in","r",stdin); while (1){ scanf("%d%d",&n,&m); if (!n) break; t=15; f[1][15]=1;f[1][12]=1;f[1][0]=1;f[1][3]=1;f[1][9]=1; for (j=0;j<=15;j++){ k=15; for (l=0;l<=3;l++) if ((1<<l)&j) k-=(1<<l); if (!j) a.a[j][15]=1,a.a[j][12]=1,a.a[j][3]=1,a.a[j][0]=1,a.a[j][9]=1; else{ a.a[j][k]=1; for (l=0;l<=2;l++) if (!((1<<l)&j) && !((1<<(l+1))&j)) a.a[j][k-(1<<l)-(1<<(l+1))]=1; } } if (n>1){ b=mi(n-1); memset(f[2],0,sizeof(f[2])); for (j=0;j<=15;j++) for (k=0;k<=15;k++) f[2][j]=(f[2][j]+f[1][k]*b.a[k][j]%m)%m; t=f[2][0]; }else t=f[1][0]; printf("%d\n",t); }}
3 0
- NOIP提高组【JZOJ4787】数格子
- JZOJ4787. 【NOIP2016提高A组模拟9.17】数格子
- {题解}[jzoj4787]【NOIP2016提高A组模拟9.17】数格子
- 【JZOJ4787】【NOIP2016提高A组模拟9.17】数格子
- 【NOIP提高组】数格子
- [JZOJ4787] 数格子
- 【JZOJ4787】数格子
- Jzoj4787 数格子
- 【jzoj4787】【数格子】【 状态压缩动态规划】【矩阵快速幂】
- 【NOIP模拟】数格子
- 【NOIP2016提高A组模拟9.17】数格子
- JZOJ 4787 【NOIP2016提高A组模拟9.17】数格子
- NOIP提高组【JZOJ4790】选数问题
- 【NOIP提高组】选数问题
- [NOIP提高组2000]方格取数
- [NOIP提高组2000]方格取数
- [NOIP提高组2001]数的划分
- 【NOIP 2016 提高组】组合数问题
- Gitlib 添加SSH KEY
- 第一章 TCP/IP协议族
- 汉字转拼音和简拼工具类分享
- Linux IO实时监控iostat命令详解
- linux内核中读写用户态文件
- NOIP提高组【JZOJ4787】数格子
- jQuery中this与$(this)的区别
- Android“沉浸式”_刨根问底
- SVN:修改已提交日志信息
- Java设计模式-工厂设计模式
- js 转换url '\ ' 至 '/'方法
- 搭建简单hls直播测试服务
- 两种方式分别修改Dialog的宽高
- 如何使用windows的计划任务?