公式
D - 植木の配置 / Arrangement of Trees 解説
by
D - 植木の配置 / Arrangement of Trees 解説
by
kyopro_friends
「\(N\) 個の区画から、隣り合わないように \(K\) 個を選ぶ」は、選ぶ区画を左右に半区画ずつふくらませることで「 \(N+1\) 個の区画に \(K\) 個のドミノを置く」と等価になります。

これは「\(K\) 個のドミノと \(N+1-2K\) 個の正方形の合計 \(N+1-K\) 個を並べる」と等価なので、「\(N+1-K\) 箇所のうちドミノを置く \(K\) 箇所を選ぶ」と思うことで \(\binom{N+1-K}{K}=\frac{(N+1-K)!}{K!(N+1-2K)!}\) 通りとなることがわかります。
分子と分母をそれぞれ \(\bmod 10^9+7\) で計算し、最後に除算を行うことで、 \(O(N + \log \mathrm{MOD})\) でこの問題を解くことができます。(制約の範囲で分母は \(0\) になりません)
実装例 (C++)
#include<bits/stdc++.h>
#include<atcoder/modint>
using namespace std;
using modint = atcoder::modint1000000007;
modint fact(int n){
modint crr = 1;
for(int i=1; i<=n; i++){
crr *= i;
}
return crr;
}
int main(){
int n, k;
cin >> n >> k;
if(n+1-k-k < 0){
cout << 0 << endl;
}else{
modint nume = fact(n+1-k);
modint deno = fact(k) * fact(n+1-k-k);
cout << (nume/deno).val() << endl;
}
}
実装例 (Python)
MOD = 10**9 + 7
N, K = map(int, input().split())
def fact(n):
crr = 1
for i in range(1, n+1):
crr = crr * i % MOD
return crr
if N+1-K-K < 0:
print(0)
else:
nume = fact(N+1-K)
deno = fact(K) * fact(N+1-K-K)
print(nume * pow(deno, -1, MOD) % MOD)
投稿日時:
最終更新:
