首页 > 其他分享 >P3158 [CQOI2011]放棋子

P3158 [CQOI2011]放棋子

时间:2023-06-08 19:57:26浏览次数:34  
标签:满足条件 cnt P3158 times 棋子 sum CQOI2011 转移

[CQOI2011]放棋子

题目描述

在一个 \(m\) 行 \(n\) 列的棋盘里放一些彩色的棋子,使得每个格子最多放一个棋子,且不同颜色的棋子不能在同一行或者同一列,有多少种方法?

例如,\(n=m=3\),有两个白棋子和一个灰棋子,下面左边两种方法都是合法的,但右边两种都是非法的。


\(1\le n,m\le 30\),\(1\le c\le 10\),总棋子数 \(\le \max (250,n\times m)\)。

思路点拨

计数问题考虑 \(dp\) ,这是本题的难点。因为数据范围的误导不好想到这个。我们看看我们需要定义那些状态,由于每一行,每一列只能填一种颜色,所以行列要记录。又因为我们需要一个个将元素插入棋盘中,所以插入到了那种颜色的棋子也是必要的。最终我们获得了初步的状态: \(f[i][j][k]\) 表示填到了第 \(i\) 中棋子,已经有 \(j\) 行,\(k\) 列的棋盘上使用棋子。

接下来考虑转移吧,我们可以枚举每一中颜色的棋子的 "统治范围",也就是那些行列只包含这种颜色。可以得到转移式:

\[f[i][j][k]=\sum_{x=0}^j \sum_{y=0}^k f[i-1][x][y]\times C_{n-x}^{j-x} C_{m-y}^{k-y} \times w_{i-x,j-y} \]

先解释一下 \(C_{n-x}^{j-x} C_{m-y}^{k-y}\) ,这是因为转移中,对于第 \(i\) 中颜色,它的统治范围是 \(i-x\) 行,\(j-y\) 列。那么我们显然是要从剩余的 \(n-x\) 行, \(m-y\) 列中选取的。转移式中还有一个转移的贡献 \(w_{i,j}\) ,相信读者们可以猜出来这是什么意思: $w_{x,y} $ 表示在一个 \(x\times y\) 的矩阵中填入 全部的 颜色 \(i\) 棋子的方案数。

Q:为什么是一个 \(x \times y\) 的矩阵呢?

A:这是因为我们转移时枚举了 \(x,y\) ,也就是棋子 \(i\) 的统治范围,那么我们多出的行数就是 \(i-x\)行, \(j-y\) 列。显然,在这些行列中可以使用的格子只有 \((i-x) \times (j-y )\) 这么多。

有的童鞋就想(一开始的我),这不是直接 \(C_{xy}^{cnt_i} =w_{x,y}\) (其中 \(cnt_i\) 表示颜色 \(i\) 的数量)就可以了吗?然后给出了如下代码:

f[0][0][0]=1;
for(int k=1;k<=col;k++)
	for(int i=0;i<=n;i++)
		for(int j=0;j<=m;j++)
			for(int x=0;x<=i;x++)
				for(int y=0;y<=j;y++)
					f[k][i][j]=(f[k][i][j]+f[k-1][x][y]*C((i-x)*(jy),a[k])%mod*C(i,x)*C(j,y)%mod)%mod;
	cout<<f[col][n][m];

OK啊这只有 $50 $ 分(这么多我已经很满意了)。

这就是因为,刚刚我们的 \(w\) 的定义不够严谨。如果在这 \(x \times y\) 的矩阵中,有某一行或者某一列没有放棋子,那么这样会算重的。为什么会算重呢?如果一行没有东西,那么在别的转移中我是不是也可以多选出这一行,那么这样不就会有问题吗?这和我们的定义是有一定出入的。这一点比较难被发现。我们重新定义 \(w_{x,y}\) 吧,就是加上每一行每一列都 必须有 棋子的方案。

这样不好搞,因为每一行列都有 至少 一个棋子的限制。这样的问题我们很容易想到使用二项式反演转换成一般的问题。我们定义 \(f(x)\) 表示 刚好 \(x\) 行满足条件的方案数。 \(g(x)\) 表示 不超过 \(x\) 行满足条件的方案数。那么有:

\[g(x)=\sum_{i=0}^x C_{x}^i f(x) \]

反演得:

\[f(x)=\sum_{i=0}^x (-1)^{x-i} C_{x}^i g(x) \]

考虑 \(g(x)\) 得求法。我们先补充完整 \(g(x)\) 得定义:\(g(x)\) 表示 不超过 \(x\) 行满足条件,全部 \(y\) 列都满足条件得方案数。我们在此基础上设, \(h(y)\) 表示在 不超过 \(x\) 行满足条件,不超过 \(y\) 行满足条件得方案数。

那么有:

\[h(y)=\sum_{i=0}^{y} C_{y}^i g(i) \]

反演的:

\[g(y)=\sum_{i=0}^{y} (-1)^{y-i}C_{y}^i h(i) \]

我们发现 \(h(y)\) 的取值十分简单求出,就是 \(C_{xy}^{cnt_i}\) ,\(cnt_i\) 表示颜色 \(i\) 的数量,为了节省变量名,下文称 \(cnt\) 。

我们将刚刚的式子回代,那么就有:

\[f(x)=\sum_{i=0}^x\sum_{j=0}^{y} (-1)^{x-i+y-j}C_{x}^{i}C_{y}^{j}C_{ij}^{cnt} \]

这个式子 \(O(nm)\) 求就可以了。每一次转移我们都需要求出每一个 \(w_{x,y}\) 的值域。所以这部分在每一次转移的时候是 \(O((nm)^2)\) 的。

现在我们会求出转移时的贡献 \(w\) 了,那么转移应该是会写与懒得写的区别了:

f[0][0][0]=1;
for(int k=1;k<=col;k++){
	memset(g,0,sizeof(g));
	for(int i=0;i<=n;i++)
		for(int j=0;j<=m;j++)
			for(int x=0;x<=i;x++)
				for(int y=0;y<=j;y++)
					g[i][j]=(g[i][j]+(C[i][x]*C[j][y]%mod*pw[i-x]*pw[j-y]+mod)%mod*C[x*y][a[k]])%mod;
	for(int i=0;i<=n;i++)
		for(int j=0;j<=m;j++)
			for(int x=0;x<=i;x++)
				for(int y=0;y<=j;y++)
					f[k][i][j]=(f[k][i][j]+f[k-1][x][y]*g[i-x][j-y]%mod*C[n-x][i-x]%mod*C[m-y][j-y]%mod)%mod;
}

时空复杂度计算

我们的 \(dp\) ,一共有 \(c\) 轮,每一次转移 \(O((nm)^2)\) ,预处理 \(O((nm)^2)\) 。总时间 \(O(cn^2m^2)\) 。

空间不会爆就完了。

标签:满足条件,cnt,P3158,times,棋子,sum,CQOI2011,转移
From: https://www.cnblogs.com/Diavolo/p/17467483.html

相关文章

  • 棋子--状态压缩dp
    题目描述:在一个N*N的棋盘上放棋子,每一个棋子的上下左右都没有棋子,也就是不相邻,一共有多少种放法?(N<=8)sample_input013sample_output1263分析:首先,我们可以逐行来摆放这些棋子,这样我们会发现,每一行的摆放状态只和上一行有关,这样我们可以采用递推的方式来解决。假设f[i......
  • 优秀的员工究竟应该是你的棋子, 还是应该成为和你同进退的合作伙伴?
    优秀的员工究竟应该是你的棋子,还是应该成为和你同进退的合作伙伴?这个问题也许99%的老板或者管理者在回答时都会选择后者,但是,能真正身体力行做到的,似乎微乎其微。一直非常佩服马云的睿智,不仅仅是他敏锐的商业眼光,更重要的是他对于员工的重视和关注,阿里巴巴在上市时候马云提出......
  • K-D Tree模板/P4169 [Violet]天使玩偶/SJY摆棋子
    \(\color{purple}\text{P4169[Violet]天使玩偶/SJY摆棋子}\)以本题为例题讲解模板怎么写。思路\(\text{K-DTree}\)是一种类二叉查找树,不过元素是多维的,所以每次对于子树的划分也是依据不同维度的。本题使用二维的\(\text{K-DTree}\),这样每次将图分成左右子树其实就是将......
  • 两个红色的棋子不可以叠在一起
    两个红色的棋子不可以叠在一起两个红色的棋子不可以叠在一起两个红色的棋子不可以叠在一起两个红色的棋子不可以叠在一起两个红色的棋子不可以叠在一起两个红色的棋子不可以叠在一起两个红色的棋子不可以叠在一起两个红色的棋子不可以叠在一起两个红色的棋子不可以叠在一......
  • 【四二学堂】python四子连珠游戏-4(落下棋子后位置记录下来。保证每个棋子能够落在准确
    代码:fromtkinterimport*importtime#画布#棋盘#鼠标左键绑定事件#落下棋子后位置记录下来。保证每个棋子能够落在准确的位置上。classGame:def__init__(self):#self.ball=ballself.clsposition=Clsposition()self.tk=Tk()......
  • 摆放棋子
    #include<iostream>#include<string.h>#include<algorithm>usingnamespacestd;constintN=1e2+10,P=1e8;intn1,n2,m1,m2;intf[N][N][15][15];intmain(){cin>>n1>>n2>>m1>>m2;f[0][0][0][0]=1;......
  • 「分治」黑白棋子的移动
    本题为3月23日23上半学期集训每日一题中A题的题解题面题目描述有2n个棋子(n≥4)排成一行,开始位置为白子全部在左边,黑子全部在右边,如下图为n=5的情形:○○○○○●●●●......
  • 洛谷P1259 黑白棋子的移动 题解
    本蒟蒻这题用的打表做法,其实也可以理解为是一种递推。先来观察一下样例:当n为7时,输出共有14行,易得输出行数为2n。ooooooo*******--oooooo--******o*oooooo******--o......
  • 【题解】P3158 [CQOI2011]放棋子
    兄弟们,我起了,一日之计在于晨呐。题意P3158[CQOI2011]放棋子有一个\(n\)行\(m\)列的棋盘和\(c\)种颜色的棋子,每种棋子有\(a_i\)个。要求不同颜色的棋子不能放......
  • 摆放棋子
    摆放棋子给定一个$n\timesm$的国际象棋棋盘(即一个$n\timesm$的方格矩阵)。我们知道传统国际象棋中,主教(象)的行走规则是只能斜走,格数不限,但不可转向。现在,我们对主......