ADPC2-D 分配颜色
Posted Jozky86
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ADPC2-D 分配颜色相关的知识,希望对你有一定的参考价值。
题意:
n*m的表格,一开始都是红色的,现在可以进行p次操作1和q次操作2
操作1: 把某一行的同学进行取反操作:即红色变为蓝色,蓝色变成红色。
操作2: 把某一列的同学进行取反操作:即红色变为蓝色,蓝色变成红色。
问多少种方案满足:执行完所有操作1和操作2之后,蓝色恰好有t个
若两个方案中的某一行或列被小A进行操作的次数不同时,则视为两种不同的方案。
题解:
题目给的是取反操作,意味着成对的相同操作是相互抵消的,因为题目问有多少种方案满足,我们可以这样去设方案:设最终实际效果下有i行被翻转,j列被翻转,什么叫最终实际效果?有些行被翻之后又给翻回去了,那就不算被翻,我们要的是最终的呈现效果。
现在有i行j列是翻转的,那么就有
i
∗
m
+
j
∗
n
−
2
∗
i
∗
j
i*m+j*n-2*i*j
i∗m+j∗n−2∗i∗j(注意横纵直线交界处是红色而不是蓝色),如果
i
∗
m
+
j
∗
n
−
2
∗
i
∗
j
=
t
i*m+j*n-2*i*j=t
i∗m+j∗n−2∗i∗j=t,且(p-i)和(q-j)都是偶数,说明这个情况是合法的,(p-i)和(q-j)是多余的操作,而多余的操作想要抵消就必须是偶数个才行。
我们就要考虑这个情况的合法方案:
很显然我们可以从n中任意选i个翻转,
C
n
i
C_{n}^i
Cni
我们也可以从m中任意选j个翻转,
C
n
j
C_{n}^j
Cnj
然后对于多余的操作p-i,我一开始想的是因为p-i一定是偶数,可以抵消,那么我们分配(p-i)/2就行,另一半部分跟着之前操作就行,那每次操作都可以选n个,那答案不就是
n
(
p
−
i
)
/
2
n^{(p-i)/2}
n(p−i)/2吗?但并不是,因为题目说了不同的方案是指:某一行或列被小A进行操作的次数不同,而与操作顺序无关,我们直接n的次幂求,会讲不同顺序的操作也看成不同操作,导致答案算多了。
那不gg了,并没有,现在我们有(p-i)/2个操作要执行,每个操作可以选任意一行,且与顺序无关,那问题转换一下,有(p-i)/2个球,现在有n个盒子,现在要把球放在盒子里,随机放,方案是多少?我们利用隔板法来做:现在有(p-i)/2+n个球,有n个盒子,每个盒子至少一个球,所有球排成一列,有(p-i)/2+n-1个间隙,在这些间隙中插入n-1个隔板,这样就可以分出n个空间,相当于n个盒子,也就是
C
(
p
−
i
)
/
2
+
n
−
1
n
−
1
C_{(p-i)/2+n-1}^{n-1}
C(p−i)/2+n−1n−1
列的也同理
详细看代码
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
using namespace std;
#define int long long
const int mod=555555555;
int C[4500][4500];
inline void init()
{
for(int i=0;i<4500;i++)
{
for(int j=0;j<=i;j++)
{
if(!j) C[i][j] = 1;
else C[i][j] = (C[i-1][j] + C[i-1][j-1]) % mod;
}
}
}
signed main()
{
init();
int n,m,p,q,t;
cin>>n>>m>>p>>q>>t;
long long ans=0;
for(int i=0;i<=min(n,p);i++)
for(int j=0;j<=min(m,q);j++){
if((p-i)&1) continue;
if((q-j)&1) continue;
if(j*n+i*m-2*i*j==t)
{
ans+=C[n][i]*C[m][j]%mod*C[n+(p-i)/2-1][n-1]%mod*C[m+(q-j)/2-1][m-1]%mod;
ans%=mod;
}
}
printf("%lld",ans);
return 0;
}
/*
10 10 200 200 0
*/
以上是关于ADPC2-D 分配颜色的主要内容,如果未能解决你的问题,请参考以下文章
c_cpp UV Index Indicator订阅PubNub并使用颜色显示UV索引值。博文的代码片段。在这里查看项目:https:/