洛谷P4831 Scarlet loves WenHuaKe
这道题告诉我们推式子的时候头要够铁。
题意
问一个\(n\times m\)的棋盘,摆上\(n\times 2\)个中国象棋的炮使其两两不能攻击的方案数,对\(998244353\)取模。
\((n\leq m\leq 2000)或(n\leq m\leq 100000且m-n\leq 10)\)。
题解
怎么两个数据范围搞搞。
显然合法方案等价于每行每列炮的数量不超过\(2\),那么每一行就必定放\(2\)个炮了。
我们记\(f(n,m)\)为答案,考虑如何归约到规模更小的问题。
那么我们枚举最后一行炮的个数,分三类情况:
\(1\)、个数为\(0\),归约到\(f(n,m-1)\)。
\(2\)、个数为\(2\)(个数为\(1\)比较麻烦后面再说),那么先枚举放在这一列的是哪两行(\(\times \frac{n(n-1)}{2}\)),接着分类讨论这两行的另一个是否相同:
如果相同,则枚举这是哪一个\((\times (m-1))\),归约到\(f(n-2,m-2)\)。
如果不同,则这两行可以合并(同一行的唯一要求就是两个列不同),只要根据有序性\(\times 2\)即可,于是归约到\(f(n-1,m-1)\)。
\(3\)、个数为\(1\),那么先枚举占了最后一列的是哪一行\((\times n)\),再枚举这一行的另一个在哪一列\((\times (m-1))\),问题就转化为\(n-1\)行\(m-1\)列,其中有一列炮的个数\(\leq 1\)的方案数。
那么考虑容斥,用总方案数减去这一列放了两个的方案数。前者就是\(f(n-1,m-1)\),对于后者,进行与情况\(2\)相似的讨论,也可以进行计算。
可以发现\(n>m\)时\(f(n,m)=0\),于是复杂度就是\(O((m-n)n)\)。
代码里为了方便我将\(m\)减去了\(n\)。
#include<cstdio>
#include<cstring>
const int mod=998244353,inv2=(mod+1)/2;
inline int add(int a,int b)
{
return (a+=b)>=mod?a-mod:a;
}
inline int sub(int a,int b)
{
return (a-=b)<0?a+mod:a;
}
inline int mul(int a,int b)
{
return (long long)a*b%mod;
}
inline int qpow(int a,int b)
{
int res=1;
for(;b;a=mul(a,a),b>>=1)
if(b&1)
res=mul(res,a);
return res;
}
int n,m;
namespace solver1
{
const int N=2005;
int memo[N][N];
inline void init()
{
memset(memo,-1,sizeof(memo));
memo[1][0]=0;
memo[2][0]=1;
memo[3][0]=6;
return;
}
int f(int n,int m)
{
if(m<0)
return 0;
if(n==0)
return 1;
if(~memo[n][m])
return memo[n][m];
int res=0;
//0
res=add(res,f(n,m-1));
//1
res=add(res,mul(mul(n,n+m-1),f(n-1,m)));
if(n>=3)
res=sub(res,mul(mul(n,n+m-1),mul(mul(mul(n-1,n-2),inv2),add(mul(n+m-2,f(n-3,m)),mul(2,f(n-2,m))))));
//2
if(n>=2)
res=add(res,mul(mul(mul(n,n-1),inv2),add(mul(n+m-1,f(n-2,m)),mul(2,f(n-1,m)))));
return memo[n][m]=res;
}
inline void main()
{
init();
printf("%d\n",f(n,m-n));
return;
}
}
namespace solver2
{
const int N=1e5+5;
int memo[N][15];
inline void init()
{
memset(memo,-1,sizeof(memo));
memo[1][0]=0;
memo[2][0]=1;
memo[3][0]=6;
return;
}
int f(int n,int m)
{
if(m<0)
return 0;
if(n==0)
return 1;
if(~memo[n][m])
return memo[n][m];
int res=0;
//0
res=add(res,f(n,m-1));
//1
res=add(res,mul(mul(n,n+m-1),f(n-1,m)));
if(n>=3)
res=sub(res,mul(mul(n,n+m-1),mul(mul(mul(n-1,n-2),inv2),add(mul(n+m-2,f(n-3,m)),mul(2,f(n-2,m))))));
//2
if(n>=2)
res=add(res,mul(mul(mul(n,n-1),inv2),add(mul(n+m-1,f(n-2,m)),mul(2,f(n-1,m)))));
return memo[n][m]=res;
}
inline void main()
{
init();
printf("%d\n",f(n,m-n));
return;
}
}
signed main()
{
scanf("%d%d",&n,&m);
if(n<=2000&&m<=2000)
solver1::main();
else
solver2::main();
return 0;
}
洛谷P4831 Scarlet loves WenHuaKe的更多相关文章
- 洛谷 P1580 yyy loves Easter_Egg I
洛谷 P1580 yyy loves Easter_Egg I 题解: 队列+字符串 #include <cstdio> #include <string> #include ...
- [洛谷2397]yyy loves Maths VI
题目背景 自动上次redbag用加法好好的刁难过了yyy同学以后,yyy十分愤怒.他还击给了redbag一题,但是这题他惊讶的发现自己居然也不会,所以只好找你 题目描述 他让redbag找众数他还特意 ...
- 洛谷P3602 Koishi Loves Segments(贪心,multiset)
洛谷题目传送门 贪心小水题. 把线段按左端点从小到大排序,限制点也是从小到大排序,然后一起扫一遍. 对于每一个限制点实时维护覆盖它的所有线段,如果超过限制,则贪心地把右端点最大的线段永远删去,不计入答 ...
- [CF327E]Axis Walking([洛谷P2396]yyy loves Maths VII)
题目大意:给一个长度为$n(1\leqslant n\leqslant24)$的序列$S$和$k(0\leqslant k\leqslant2)$个数. 求有多少种$S$的排列方式使得其任何一个前缀和 ...
- [洛谷1580]yyy loves Easter_Egg I
题目背景 Soha的出题效率着实让人大吃一惊.OI,数学,化学的题目都出好了,物理的题还没有一道.于是,Huntfire,absi2011,lanlan对soha进行轮番炸,准备炸到soha出来,不料 ...
- 洛谷P2397 yyy loves Maths VI (mode)
P2397 yyy loves Maths VI (mode) 题目背景 自动上次redbag用加法好好的刁难过了yyy同学以后,yyy十分愤怒.他还击给了redbag一题,但是这题他惊讶的发现自己居 ...
- 洛谷P2396 yyy loves Maths VII
P2396 yyy loves Maths VII 题目背景 yyy对某些数字有着情有独钟的喜爱,他叫他们为幸运数字;然而他作死太多,所以把自己讨厌的数字成为"厄运数字" 题目描述 ...
- 洛谷——P2393 yyy loves Maths II
P2393 yyy loves Maths II 题目背景 上次蒟蒻redbag可把yyy气坏了,yyy说他只是小学生,蒟蒻redbag这次不坑他了. 题目描述 redbag给了yyy很多个数,要yy ...
- 洛谷 P4882 lty loves 96! 解题报告
P4882 lty loves 96! 题目背景 众所周知,\(lty\)非常喜欢\(96\)这两个数字(想歪的现在马上面壁去),更甚于复读(人本复)! 题目描述 由于爱屋及乌,因此,\(lty\)对 ...
随机推荐
- memset()初始化为1的那些事
问题代码: #include <stdio.h> #include <string.h> int main() { ]; int a; while(~scanf("% ...
- C语言各种数据类型取值范围
速查表: char -128 ~ +127 1Byte -2^7 ~ 2^7-1 unsigned char 0 ~ 255 1Byte 0 ~ 2^8-1 short -32767 ~ + 3276 ...
- 汽车为什么选择了CAN总线技术?
汽车为什么选择了CAN总线技术? 围绕“汽车为什么选择了CAN总线技术?汽车CAN总线技术到底是怎么一回事?采用汽车CAN总线技术有哪些优点?汽车总线的发展趋势”等问题作了一个浅短的介绍: 1. 汽车 ...
- 基于多进程和基于多线程服务器的优缺点及nginx服务器的启动过程
基于多进程服务器的优点: 1.由操作系统进行调度,运行比较稳定强壮 2.能够方便地通过操作系统进行监控和管理 例如对每个进程的内存变化状况,甚至某个进程处理什么web请求进行监控.同时可以通过给进程发 ...
- 20155202《网络对抗》Exp8 Web基础
20155202<网络对抗>Exp8 Web基础 基础问题回答 什么是表单? 表单是一个包含表单元素的区域,表单元素是允许用户在表单中(比如:文本域.下拉列表.单选框.复选框等等)输入信息 ...
- web窗体的运用
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace WebAp ...
- python 回溯法 子集树模板 系列 —— 13、最佳作业调度问题
问题 给定 n 个作业,每一个作业都有两项子任务需要分别在两台机器上完成.每一个作业必须先由机器1 处理,然后由机器2处理. 试设计一个算法找出完成这n个任务的最佳调度,使其机器2完成各作业时间之和达 ...
- python 单体模式 的几种实现
这是本人的一篇学习笔记. 本文用 python 实现单体模式,参考了这里 一.修改父类的 __dict__ class Borg: _shared_state = {} def __init__(se ...
- GIT命令基本使用
记录摘选自廖雪峰的官方网站归纳总结 1.centos下安装git [root@cdw-lj ~]# yum install git 2.配置用户名以及邮箱 [root@cdw-lj opt]# git ...
- mybatis 异常 too many connections 解决方案 mysql
参考: https://blog.csdn.net/u011628250/article/details/54017481 https://www.cnblogs.com/baby123/p/5710 ...