题目描述

小$A$和小$B$在做游戏。
他们找到了一个$n$行$m$列呈网格状的画板。小$A$拿出了$p$支不同颜色的画笔,开始在上面涂色。看到小$A$涂好的画板,小$B$觉得颜色太单调了,于是把画板擦干净,希望涂上使它看起来不单调的颜色(当然,每个格子里只能涂一种颜色)。小$B$想知道一共有多少种不单调的涂色方案。我们定义一个涂色方案是不单调的,当且仅当任意相邻两列都出现了至少$q$种颜色。


输入格式

一行四个整数$n,m,p,q$,意义如题中所述。


输出格式

一行一个整数,表示不单调的涂色方案数模$998244353$的值。


样例

样例输入:

2 3 3 3

样例输出:

162


数据范围与提示

对于$20\%$的数据:$n\times m\leqslant 15,q\leqslant p\leqslant 3$
对于另外$20\%$的数据:$n\leqslant 7,m\leqslant 100,p=q=2$
对于另外$30\%$的数据:$n\leqslant 100,m\leqslant 1,000,q\leqslant p\leqslant 100$
对于$100\%$的数据:$n\leqslant 100,m\leqslant {10}^9 ,q\leqslant p\leqslant 100$


题解

首先,明确题意,不能不涂(也是被这个我并没有看出来的条件坑死了……)

静观数据范围,显然是矩阵快速幂。

那么,我们现在思考如何构建转移矩阵。

先把矩阵搁在一边,考虑$DP$,设$f[i][j]$表示对于一列,选到了第$i$行的格子,恰好涂了$j$种颜色的方案数,直接给出式子:

$$f[i][j]=f[i-1][j-1]\times (p-(j-1))+f[i-1][j]\times j$$

前半部分的转移即为又选了一个新的,那么我就要在这么多的颜色中再选一个;后半部分相当于我又从原来的$j$中颜色中选了一种涂在了这里。

那么,我们在设$g[j]$表示对于一列,选了$j$种颜色的方案数,那么根据第二类斯特林数(类比将$n$个有区别的小球放进$m$个没有区别的盒子,每个盒子至少放一个小球),一列中涂上每种$j$元颜色集合的颜色的方案数就是$\frac{g[j]}{C_p^j}$。

那么,我们对于这一列用了$j$元集合,下一列要用$k$元集合,则方案数为:

$$\sum \limits_{x=\max(q,j,k)}^{\min(p,j+k)}C_j^{j+k-x}C_{p-i}^{x-j}$$

解释一下上式,考虑两个极端情况,$\alpha.j\cup k=\varnothing$,$\beta.j\subset k\ or\ k\subset j$,这也是上式的上下线;再来理解组合数,因为$j$和$k$会有交集,所以前一个组合数就是交集,而第二个就是交集以外的。

现在,我们令:

$$trans[j][k]=\frac{g[j]}{C_p^j}\sum \limits_{x=\max(q,j,k)}^{\min(p,j+k)}C_j^{j+k-x}C_{p-i}^{x-j}$$

那么,$dp[i][k]=dp[i-1][j]\times [j][k]$,$dp[1][j]=g[j]$。

这样我们就可以拿到$70$分了。

观察式子,可以用矩阵快速幂快速转移。

时间复杂度:$\Theta(n^3\log m)$。

期望得分:$100$分。

实际得分:$100$分。


代码时刻

#include<bits/stdc++.h>
using namespace std;
const int mod=998244353;
int n,m,p,q;
long long C[1001][1001],g[101][101];
long long wzc[101][101],ans[101][101],flag[101][101];
void matrix1()
{for(int i=1;i<=n;i++)for(int j=1;j<=n;j++){flag[i][j]=ans[i][j];ans[i][j]=0;}for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)for(int k=1;k<=n;k++)ans[i][j]=(ans[i][j]+flag[i][k]*wzc[k][j]%mod)%mod;
}
void matrix2()
{for(int i=1;i<=n;i++)for(int j=1;j<=n;j++){flag[i][j]=wzc[i][j];wzc[i][j]=0;}for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)for(int k=1;k<=n;k++)wzc[i][j]=(wzc[i][j]+flag[i][k]*flag[k][j]%mod)%mod;
}
void pre_work()
{g[0][0]=C[0][0]=1;for(int i=1;i<=100;i++){C[i][0]=ans[i][i]=1;for(int j=1;j<=i;j++)C[i][j]=(C[i-1][j]+C[i-1][j-1])%mod;}
}
int main()
{scanf("%d%d%d%d",&n,&m,&p,&q);pre_work();m--;for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)g[i][j]=j*(g[i-1][j]+g[i-1][j-1])%mod;for(int j=1;j<=p;j++)for(int k=1;k<=p;k++){for(int x=max(max(q,j),k);x<=min(p,j+k);x++)wzc[j][k]=(wzc[j][k]+C[j][j+k-x]*C[p-j][x-j]%mod)%mod;wzc[j][k]=wzc[j][k]*g[n][k]%mod;}while(m){if(m&1)matrix1();matrix2();m>>=1;}for(int i=1;i<=p;i++)for(int j=1;j<=p;j++)ans[0][0]=(ans[0][0]+ans[i][j]*C[p][i]%mod*g[n][i]%mod)%mod;printf("%lld",ans[0][0]);return 0;
}


rp++

转载于:https://www.cnblogs.com/wzc521/p/11598358.html

[CSP-S模拟测试]:涂色游戏(DP+组合数+矩阵快速幂)相关推荐

  1. 【POJ - 3744】Scout YYF I(概率dp,矩阵快速幂优化dp)

    题干: 题目大意: 在一条不满地雷的路上(无限长),你现在的起点在1处.在N个点处布有地雷,1<=N<=10.地雷点的可能坐标范围:[1,100000000]. 每次前进p的概率前进一步, ...

  2. bzoj 1009: [HNOI2008]GT考试(dp+kmp+矩阵快速幂)

    1009: [HNOI2008]GT考试 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 3932  Solved: 2398 [Submit][Sta ...

  3. 【LOJ #6617】「THUPC 2019」摆家具 / furniture(DP / BSGS / 矩阵快速幂)

    传送门 首先显然k=lognk=lognk=logn 显然对于每个iii我们只用关注有多少位与询问的数字不同 考虑分成两个部分 先对每个数字iii求出与他有jjj位不同的数字价值之和 再求出ttt轮后 ...

  4. 【NOIP 模拟赛】平均数 涂色游戏 序列题解

    吐槽(完跪):神tmNOIP模拟赛,看到大题头根本高级数据结构什么的想都没想,结果死的很惨,第三题竟然要可持久化线段树,这NOIP我服了. 平均数: 这道题40分相信大家都能拿到,剩下的60分讲真考验 ...

  5. 【noip2016十连测round3】T3 涂色游戏 【矩阵快速幂优化dp】

    涂色游戏 题解: 推一推公式. 我们让f[i][j]表示第i列有j种颜色的方案总数,k表示i-1列用了多少种颜色,l表示第i列用了多少种没有在i-1列出现的颜色,G(i,j)表示i个格子涂j种颜色的方 ...

  6. LYDSY模拟赛day3 涂色游戏

    /* 非常好的题 */ #include <cstdio> #include <iostream> #include <cstdlib> #include < ...

  7. c语言写一个格子涂色的游戏,不一样的涂色游戏小程序,这个魔力贴贴涂色游戏有点意思...

    原标题:不一样的涂色游戏小程序,这个魔力贴贴涂色游戏有点意思 30000+游戏爱好者已加入我们! 沐沐带你发现好游戏! <魔力贴贴>游戏小程序好玩吗? <魔力贴贴>小游戏怎么玩 ...

  8. qduoj LC的涂色游戏(快速幂)

    题目链接:https://qduoj.com/problem/12/点击打开链接 LC的涂色游戏 发布时间: 2015年9月19日 21:42   时间限制: 1000ms   内存限制: 256M ...

  9. NOI Online #2 提高组 第一题:涂色游戏

    NOI Online #2 提高组 第一题:涂色游戏 前言 题目 解析 代码 前言 呦呵,这道题我竟然爆零了 而且我的暴力dfs死循环了!\bold{\Large\xcancel\text{而且我的暴 ...

最新文章

  1. Spring5-IOC容器实现方式
  2. linux shell之find高级点的用法
  3. 台达n2系列变频器_台达变频器C2000系列在Profibus网络中的应用
  4. Pyhton——动态语言
  5. SpringMVC简单小案例
  6. html----学习笔记
  7. jQuery实现左移右移
  8. protobuf 编码实现解析(java)
  9. 关于random的多种用法
  10. 星球大战telnet_重制星球大战:第四集(1977)
  11. Linux系统提高编辑效率的vim工具重要知识
  12. 带时间窗的车辆路径规划问题(VRPTW)
  13. 四网协同之WLAN专利分析与启示
  14. AM437X系列编译环境搭建
  15. matlab读取视频VideoRead用法
  16. uni-app修改页面背景色
  17. 强力推荐90个优秀外国英文网站
  18. virtualbox出现failed to attach usb,VERR_PDM_NO_USB_PORTS问题解决
  19. Centos下samba共享打印机
  20. 图像数据的特征提取方法

热门文章

  1. 2017-2018 ACM-ICPC Asia East Continent League Final (ECL-Final 2017)
  2. 关于unity连接MySQL数据库做一个简单的登陆注册系统
  3. 计算机制作动画的优势,产品三维动画制作的表现优势
  4. 服务器cpu组装超性价比电脑,如何配置组装一台性价比高的电脑?
  5. Flutter写第一个跨平台薅羊毛APP(五)--如何运营这个APP
  6. FrameWork之旅 -- Activity过去的门面ActionBar
  7. android 读取 caf格式,CAF 文件扩展名: 它是什么以及如何打开它?
  8. 龙叔学ES:Elasticsearch XPACK安全认证
  9. android 多点触控缩放,【移动开发】Android中图片的多点触控和缩放
  10. OSGI+Equinox+idea HelloworldDemo