题解 P6076 [JSOI2015]染色问题

ps:感觉容斥对初学者而言很玄学(至少本人刚开始接触时是这样...),所以想写一篇题解,仔细分析容斥到底如何运用到题目中。

容斥

容斥解决的是满足多个条件的方案数的问题,这里可以把每个条件转化为集合(如果对集合的运算还不是很了解的同学,可以先了解集合的基本运算,这会对容斥的理解帮助很大),例:

*|U|:所有情况的方案数
*Si:满足条件i的方案数
*|i=1nSi|:满足任一一个条件的方案数
*|i=1nSi|:全部条件都满足的方案数

容斥的核心思想是对“至少(至多)”和“恰好(一般是)”之间的转换,重点是弄清楚哪种方案数容易求,相关的式子如下:

*|i=1nSi|=m=1n(1)m1ai<ai+1|i=1mSai|
*|i=1nSi|=|U||i=1nSi¯|

问题描述:

一个n×m的棋盘,用c种颜色染色,求满足条件的方案数

  • 棋盘的每一个小方格既可以染色(染成c种颜色中的一种),也可以不染色。
  • 棋盘的每一行至少有一个小方格被染色。
  • 棋盘的每一列至少有一个小方格被染色。
  • 每种颜色都在棋盘上出现至少一次。

看上去很难,既要考虑颜色,又要考虑每一行,每一列,感觉特别不可做...

我们先将颜色单独考虑。

发现“出现至少一次”可以看成每种颜色都要用,即|i=1nSi|,而我们发现如果有某几种颜色不用,其它颜色不考虑用不用的方法好像很好求((其它颜色数+1)^要填的格子数),即|i=1nSi¯|。通过式子一和式子二共同转化,|i=1nSi|=|U||i=1nSi¯|=|U|m=1n(1)m1ai<ai+1|i=1mSai|

ai<ai+1|i=1mSai¯|的意义是所有组m个颜色不用的方案数,组数就是c种颜色中选m种颜色,即(Cm)组,为了表述方便,我们设f[i]表示在棋盘上用最多用i种颜色满足要求一、二的方案数(这个待会去求),而一组的答案就为f[cm],与组数相乘即可,而全集是f[c](最多用c种颜色就是所有情况)。所以答案为ans=f[c]i=1cf[ci](ci)(1)i1

类似的,计算f[i]的时候所要考虑的要求一、二,也可以通过上面的容斥分析得到。还是通过上面的式子转化,不过此时的aj<aj+1|j=1kSaj¯|就是所有组k列完全不涂色的方案数,一组的答案这么统计:对每一行单独考虑,答案数为(i+1)mk,可是一行不能全为空,就要减去一,n行都是独立的,相乘就是((i+1)mk1)n。这里全集就是当k=0时的值(0列完全不涂色就是所有的情况),所以f[i]=((i+1)m1)nk=1m(mk)((i+1)k1)n(1)k1

综合起来就可以了。

代码:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const ll mod=1e9+7;
ll n,m,c,f[410],C[410][410];
ll ksm(ll x,int y){
	ll ans=1;
	while(y){
		if(y&1)ans=ans*x%mod;
		x=x*x%mod,y=y>>1;
	}
	return ans;
}
int main(){
	cin>>n>>m>>c;
	for(int i=0;i<=400;i++){
		C[i][0]=1;
		for(int j=1;j<=i;j++){
			C[i][j]=(C[i-1][j-1]+C[i-1][j])%mod;
		}
	}
	for(ll i=1;i<=c;i++){
		ll st=0,k=1;
		for(int j=m;j>=1;j--,k=k*(i+1)%mod){
			if(j&1)
				st=(st+ksm(k-1,n)*C[m][j])%mod;
			else
				st=(st-ksm(k-1,n)*C[m][j]%mod+mod)%mod;
		}
		f[i]=(ksm(ksm(i+1,m)-1,n)-st+mod)%mod;
	}
	ll ans=f[c],an1=0;
	for(int i=1;i<=c;i++){
		if(i&1)
			an1=(an1+f[c-i]*C[c][i])%mod;
		else
			an1=(an1-f[c-i]*C[c][i]%mod+mod)%mod;
	}
	cout<<(ans-an1+mod)%mod;
	return 0;
}

本文作者:qwq123

本文链接:https://www.cnblogs.com/qwq-123/p/15904957.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   qwq_123  阅读(60)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起