Kawazoe(@riverplus)さん出題の問題です。
問題とテストケースはこちらのお世話になりました。解答もあります。
->https://blog.goo.ne.jp/r-de-r/e/3f51395af1c1d9b98d6c2488ab3aa3c9
Aがk枚残ればBもk枚のこり、ペアの枚数もAと同数です。
Aのペアの組数 x=(n-k)/2=div(n-k,2)としますと
Aのペアの組み合わせの数はn組からx組選ぶ場合の数 -> nCx
Bのペアの組み合わせの数はn-x組からx組選ぶ場合の数 -> (n-x)Cx
残りk組は2枚のカードを区別するのでどちらがAに行くか -> 2^k
全体の組み合わせの数 -> (2*n)Cn
となり、
F(n,k)=nCx * (n-x)Cx * 2^k / (2*n)Cn
計算途中巨大な数になりますのでJuliaではBigIntが必要でしたが、
nCrに対応するbinomialという関数がありますので楽です。
#julia ver 1.41,1.53,1.73
function solve(n,k,a)
n = BigInt(n)
k = BigInt(k)
x = div(n-k,2)
ret = Int(trunc(binomial(n,x) * binomial(n-x,x) * 2^k / binomial(2*n,n) * 10^6))
s = a == ret ? "ok " : "no "
println(s,ret)
end
solve(2, 2,666666)
solve(4, 2,685714)
solve(5, 1,238095)
solve(13, 9,211187)
solve(30, 20,67130)
solve(41, 17,126481)
solve(80, 24,226)
solve(99, 47,137249)
場合の数の数え方はいろいろあって
ペアでないカードはn組からk組を選び2枚を区別するので組み合わせの数 -> nCk * 2^k
Aのペアはn-k組からx組選ぶので組みあわせの数 -> (n-k)Cx
全体の組み合わせの数 -> (2*n)Cn
F(n,k)=nCk * 2^k * (n-k)Cx / (2*n)Cn
等でも良いのでPrologではこちらの式を使いました。
%SWI-Prolog ver 7.42,7.64
%:-initialization(start). %ideone
%start.
ncr(_,0,1).
ncr(N,1,R):-R is N.
ncr(N,M,R):-N1 is N-1,M1 is M-1,ncr(N1,M1,R1),R is R1*N div M,!.
res(N,K,R):-
N1 is N-K,N2 is (N-K)/2,ncr(N,K,R1),ncr(N1,N2,R2),ncr(2*N,N,R3),
R is floor(R1 * 2^K * R2 / R3 * 10^6) .
solve(N,K,A):-
(res(N,K,R)->(R==A->Str=" ok ";Str=" no ");
write(fail)),write(" "),write(Str),writeln(R),!.
start:-f2(N,K,A),solve(N,K,A),fail.
start.
f2(2, 2,666666).
f2(4, 2,685714).
f2(5, 1,238095).
f2(13, 9,211187).
f2(30, 20,67130).
f2(41, 17,126481).
f2(80, 24,226).
f2(99, 47,137249).