[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;
}