排列组合 get !
组合数
1.公式 :
2.递推式:
3.性质:
和一些其他性质:
证明:
传送门
这其实就是一个简单的快速幂,
但是证明了组合数的一个性质
即:
由于这个需要二项式定理证明,在下太蒟就不证了。
但是可以这样想,对于每一个数,只有取或不取两种状态,所以
代码就不放了,就是一个快速幂。
排列:
1.公式:
2.与组合数转化:
t1:
传送门
这道题 需要的是逆向思维,
求相邻罪犯状态相同的方案数,可以先求出总方案数,再减去状态不同的方案数,
总方案数显然是 m ^ n
相邻罪犯状态不相同的方案数可能需要想一下,
对于第一个罪犯,选择的方案数是 n ,
对于后面的罪犯,为了与前面的不相同,选择的方案数是 n - 1
所以,答案就是 m ^ n - m * ( m - 1 ) ^ ( n - 1 )
int main(void)
{
cin >> m >> n;
LL tot = FastPow(m,n)%p;
LL els = m*FastPow(m-1,n-1)%p;
LL ans = tot-els;
cout << (ans+p)%p;
return 0;
}
t2:
传送门
与上一题挺像的,也是先求出所有组合,再减去不合法的情况
不合法的情况即是没有任何一块长为 k 的区间颜色相同
int main(void)
{
cin >> n >> m >> k;
f[0] = 1;
LL tot = FastPow(m,n)%p;
for(int i=1;i<=n;i++)
{
if(i < k)
{
f[i] = f[i-1]*m%p;
sum = (sum+f[i])%p;
}
else
{
f[i] = sum*(m-1)%p;
sum = (sum+f[i]-f[i-k+1])%p;
}
}
LL ans = tot - f[n];
cout << (ans+p)%p;
return 0;
}