[TK] Bulls And Cows S

形式化题意

在长度为 \(n\) 的序列中放两种元素 \(F\)\(M\),使得相邻的 \(M\) 之间的距离不超过 \(k\). 求方案数.

思路分析

考虑分特殊情况考虑.

特殊情况一 没有 \(M\)

方案一定成立,为 \(1\).

再考虑剩下的情况,那么一定是有 \(M\) 的了.

特殊情况二 \(k=1\)

这种情况其实就是需要 \(M\) 不能相邻. 根据排列组合知识可以发现这是插空法. 首先在 \(n\) 个元素中计算出 \(F\)\(n-M\) 个,那么先将它们随机排布,会形成 \(n-M+1\) 个空位,然后考虑将 \(M\) 放进空位里,方案数为 \(C^{M}_{n-M+1}\)

通解分析

注意到特殊情况二十分好算,那么我们有办法将任意的 \(k\) 都转化为这种情况吗. 实际上是可以的. 当 \(k=k_{1}\) 时,可以得出任意相邻的 \(M\) 之间的距离 \(l_{i}\) 都满足 \(l_{i}\ge k_{1}\). 那么我们将 \(l_{i}\) 同时减少 \(k_{1}-1\),不会影响最后的计算结果. 这其实是利用了捆绑 \(F\) 组合的思想. 那么这道题的答案就十分明显了,为

\[ans=1+\sum_{i} C^{i}_{n-(i-1)(k-1)-i+1} \]

代码实现

int main(){
	long long n,k,ans=0;
	cin>>n>>k;
	for(long long i=1;2*i<=n+2;++i){
		ans+=lucas(n-i+1,i);
		ans%=p;
		n-=k-1;
	}
	cout<<ans+1;
}
posted @ 2024-04-13 17:28  HaneDaniko  阅读(12)  评论(0编辑  收藏  举报