这道题告诉我们推式子的时候头要够铁。

题意

问一个\(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的更多相关文章

  1. 洛谷 P1580 yyy loves Easter_Egg I

    洛谷 P1580 yyy loves Easter_Egg I 题解: 队列+字符串 #include <cstdio> #include <string> #include ...

  2. [洛谷2397]yyy loves Maths VI

    题目背景 自动上次redbag用加法好好的刁难过了yyy同学以后,yyy十分愤怒.他还击给了redbag一题,但是这题他惊讶的发现自己居然也不会,所以只好找你 题目描述 他让redbag找众数他还特意 ...

  3. 洛谷P3602 Koishi Loves Segments(贪心,multiset)

    洛谷题目传送门 贪心小水题. 把线段按左端点从小到大排序,限制点也是从小到大排序,然后一起扫一遍. 对于每一个限制点实时维护覆盖它的所有线段,如果超过限制,则贪心地把右端点最大的线段永远删去,不计入答 ...

  4. [CF327E]Axis Walking([洛谷P2396]yyy loves Maths VII)

    题目大意:给一个长度为$n(1\leqslant n\leqslant24)$的序列$S$和$k(0\leqslant k\leqslant2)$个数. 求有多少种$S$的排列方式使得其任何一个前缀和 ...

  5. [洛谷1580]yyy loves Easter_Egg I

    题目背景 Soha的出题效率着实让人大吃一惊.OI,数学,化学的题目都出好了,物理的题还没有一道.于是,Huntfire,absi2011,lanlan对soha进行轮番炸,准备炸到soha出来,不料 ...

  6. 洛谷P2397 yyy loves Maths VI (mode)

    P2397 yyy loves Maths VI (mode) 题目背景 自动上次redbag用加法好好的刁难过了yyy同学以后,yyy十分愤怒.他还击给了redbag一题,但是这题他惊讶的发现自己居 ...

  7. 洛谷P2396 yyy loves Maths VII

    P2396 yyy loves Maths VII 题目背景 yyy对某些数字有着情有独钟的喜爱,他叫他们为幸运数字;然而他作死太多,所以把自己讨厌的数字成为"厄运数字" 题目描述 ...

  8. 洛谷——P2393 yyy loves Maths II

    P2393 yyy loves Maths II 题目背景 上次蒟蒻redbag可把yyy气坏了,yyy说他只是小学生,蒟蒻redbag这次不坑他了. 题目描述 redbag给了yyy很多个数,要yy ...

  9. 洛谷 P4882 lty loves 96! 解题报告

    P4882 lty loves 96! 题目背景 众所周知,\(lty\)非常喜欢\(96\)这两个数字(想歪的现在马上面壁去),更甚于复读(人本复)! 题目描述 由于爱屋及乌,因此,\(lty\)对 ...

随机推荐

  1. C++之静态的变量和静态函数

    到目前为止,我们设计的类中所有的成员变量和成员函数都是属于对象的,如我们在前面定义的book类,利用book类声明两个对象Alice和Harry,这两个对象均拥有各自的price和title成员变量, ...

  2. php连接mysql...mysqli和mysql

    mysql_connect()这一系列函数已经不推荐使用了,不安全. <?php $con = mysql_connect('localhost','root','');// 选择连接数据库系统 ...

  3. React Native创建一个APP

    React Native 结合了 Web 应用和 Native 应用的优势,可以使用 JavaScript 来开发 iOS 和 Android 原生应用.在 JavaScript 中用 React 抽 ...

  4. 小R的烦恼 BZOJ3280

    分析: 一开始一直Wa,发现是建图建错了,必须得拆点. S连i,流量为a[i],费用为0,i+n连T,流量同上,费用为0,之后i连i+1费用为0,流量为inf,之后S连n*2+i,流量为li,费用为0 ...

  5. mvn dependency:tree

    jar依赖冲突解决实践 前言 随着功能的增多,各种中间件的引入.应用以来的各种jar的规模极具膨胀,出现jar冲突和Class冲突的问题层出不穷,让人不胜其扰.本文针对冲突,提供一个排查和定位问题的最 ...

  6. 你也可以自己写一个可爱 & 小资风格的Android加载等待自定义View - 转

    http://blog.csdn.net/carson_ho/article/details/77712072

  7. Tomcat端口被占用解决方案

    Tomcat端口被占用解决方法 1.在dos下,输入 netstat -ano|findstr 8080 //说明:查看占用8080端口的进程,显示占用端口的进程 2.taskkill /pid 19 ...

  8. 20155223 Exp8 WEB基础实践

    20155223 Exp8 WEB基础实践 基础问题回答 什么是表单? 表单是一个包含表单元素的区域. 表单元素是允许用户在表单中(比如:文本域.下拉列表.单选框.复选框等等)输入信息的元素. 表单使 ...

  9. 20155227《网络对抗》Exp2 后门原理与实践

    20155227<网络对抗>Exp2 后门原理与实践 基础问题回答 (1)例举你能想到的一个后门进入到你系统中的可能方式? 在非官方网站下载软件时,后门很可能被捆绑在软件中. 攻击者利用欺 ...

  10. Getting Start chrome-extension demo

    写一个小小的chrome扩展demo~ 准备工作 了解一下插件chrome-extension: 在应用商店里的插件基本上都是以.crx为文件后缀,该文件其实就是一个压缩包,包括插件所需要的html. ...