X



トップページ数学
1002コメント417KB
分からない問題はここに書いてね448
■ このスレッドは過去ログ倉庫に格納されています
0194132人目の素数さん
垢版 |
2018/10/28(日) 20:30:37.13ID:x624ZJMX
>>161の若干の一般化とその導出を備忘録的に書いておきます。

>>60
まず、部屋を探る順番が一般の場合を考える。
部屋がNあり、その集合をRとする。A君、B君が探る順番を表わす全単射写像をそれぞれf,gとする:
f,g: R→{0,1,…,N-1} (順番は0から始まるとする。)
部屋自体の位置はなんら答えに影響しない。
σ=g・f^{-1} と置くと、σは{0,1,…,N-1}の置換。(・は写像の合成)
A君がi番目に探る部屋はB君がσ(i)番目に探る部屋ということ。
以下、「A君がi番目に探る部屋」のことを「部屋i」ということにする。

求めたいのは、「A君がB君よりも早く宝を見つける宝の配置の数」であるが、宝の数をcとすると、それは
 Σ[σ(i)>i] binomial(#{j| j>i, σ(j)>i}, c-1) (0≦i,j≦N-1、binomialは二項係数)
である。
なぜか?
「A君が初めて宝を見つける部屋(部屋iとする)」で場合分けしよう。
(つまり部屋0〜i-1には宝がなく、部屋iに宝がある場合)
部屋iはB君がσ(i)番目に探る部屋だからσ(i)>iでないと
少なくともB君はA君よりも前か同時に部屋iで宝を見つける
(B君はその前に別の部屋で宝を見つけることもある)ことになりA君は勝てない。
したがって、σ(i)>iが必要。
残りのc-1個の宝は部屋i+1〜N-1にあるが、宝がある部屋を部屋jとすると、
やはりσ(j)>iでないといけない。逆に全部の宝でそうであればA君が勝つ。
よって、残りのc-1個の宝が置かれてもいい部屋の数は#{j| j>i, σ(j)>i}だけあり、
全部そこに置かれる場合はbinomial(#{j| j>i, σ(j)>i}, c-1)通り。
したがって、上記のようになる。

続く
0195132人目の素数さん
垢版 |
2018/10/28(日) 20:31:26.72ID:x624ZJMX
>>194
続き

部屋が縦m、横nで、A君は横1行を探し終えたらすぐ下の1行に移り、
B君は縦1列を探し終えたらすぐ右の1列に移るという場合を考える。
つまり、m=4,n=3の場合、A君は
0123
4567
891011
B君は
0369
14710
25811
という順番で探す。
このとき、σ=0,3,6,9,1,4,7,10,2,5,8,11。
一般には、σ(nk+l)=ml+k (0≦k≦m-1, 0≦l≦n-1)。

ここまでをPythonで表すと:
#二項係数。SageMathでは定義ずみ
def binomial(n,r):
from math import factorial as f
return f(n)//f(r)//f(n-r) if r>=0 and n-r>=0 else 0

#置換p、宝c個で勝つ宝の配置の数
def nwinperm(p,c):
N = len(p)
return sum(binomial(len([j for j in range(i+1, N) if i<p[j]]),c-1)
for i in range(N) if i<p[i])

#部屋が縦m、横nのときの置換
def rectperm(m,n):
return [m*l+k for k in range(m) for l in range(n)]

#部屋が縦m、横n、宝がc個で横優先が勝つ宝の配置の数
def nwinrect0(m,n,c):
return nwinperm(rectperm(m,n),c)

続く
0196132人目の素数さん
垢版 |
2018/10/28(日) 20:32:10.70ID:x624ZJMX
>>195
続き

部屋が縦m、横nの場合を考えているが、もう少し計算を進める。
#{j| j>i, σ(j)>i} をこの場合に具体的に表そう。

i,j (0≦i,j≦mn-1)をそれぞれ nk+l, nk'+l' (0≦k,k'≦m-1, 0≦l,l'≦n-1) とする。
σ(i)>i ⇔ lm+k>nk+l ⇔ (m-1)l>(n-1)k、
j>i ⇔ nk+l>nk'+l' ⇔ 「k=k' かつ l<l'」または「k<k'」、
σ(j)>i ⇔ l'm+k'>nk+l ⇔ l' + k'/m > (nk+l)/m [ここで nk+lをmで割った商をq、余りをrとすると]
   ⇔ l' + k'/m > q + r/m ⇔ 「q≦l'≦n-1 ただし l'=q, k'≦r を除く」
を使って
#{j| j>i, σ(j)>i} = #{(k',l')|『「k=k' かつ l<l'」または「k<k'」』かつ l'm+k'>nk+l}
に出てくる『「k=k' かつ l<l'」または「k<k'」』かつ l'm+k'>nk+lを満たす組(k',l')の数を求める。
k=k' かつ l<l'のとき σ(i)>iからlm+k>nk+lだからl'm+k'>nk+lは常に成り立つので、l<l'≦n-1でn-1-l個。
k<k' のとき l'm+k'>nk+l ⇔ 「q≦l'≦n-1, k<k'≦m-1 ただし l'=q, k<k'≦r を除く」だから
(n-q)(m-1-k) - (r-k)δ(r>k)個、ただしδ(P)はPが真なら1、偽なら0である関数。
よって、#{j| j>i, σ(j)>i} = (n-1-l) + (n-q)(m-1-k) - (r-k)δ(r>k)。
したがって、求める数は
Σ[0≦k≦m-1, 0≦l≦n-1, (m-1)l>(n-1)k] binomial((n-1-l) + (n-q)(m-1-k) - (r-k)δ(r>k), c-1)。

これを使ったPythonコード:
#nloc(m,n,k,l)は縦m、横nの部屋で横優先が部屋(k,l)で初めて宝を発見する場合で
#宝が置かれても縦優先に先を越されない部屋の数。
def nloc(m,n,k,l):
q,r = divmod(n*k+l,m)
return (n-1-l) + (n-q)*(m-1-k) - (r-k if r > k else 0)

#部屋が縦m、横n、宝がc個で横優先が勝つ宝の配置の数
def nwinrect1(m,n,c):
return sum(binomial(nloc(m,n,k,l),c-1) for k in range(m) for l in range(n) if (m-1)*l>(n-1)*k)

続く
0197132人目の素数さん
垢版 |
2018/10/28(日) 20:34:35.87ID:x624ZJMX
>>196
続き

部屋がm×(m+1) (n=m+1) のとき。
(m-1)l>(n-1)k ⇔ 0≦k≦m-2 かつ k+1≦l≦m。
(nk+l)/m = k + (k+l)/m より k+l<mのときq=k,r=k+l、k+l≧mのときq=k+1,r=k+l-m。
r>k (k+l<m)とr≦k (k+l≧m)とに分けるように場合分けをする:
@0≦k≦[(m-1)/2], k+1≦l≦m-k-2 のとき r>k、
A[(m+1)/2]≦l≦m-1, m-1-l≦k≦l-1 または Bl=m, 0≦k≦m-2 のとき r≦k。

m=6のとき
×@@@@AB
××@@AAB
×××AAAB
××××AAB
×××××AB
×××××××

m=7のとき
×@@@@@AB
××@@@AAB
×××@AAAB
××××AAAB
×××××AAB
××××××AB
××××××××

後はΣの計算。>>60に合わせるとQ君がA君の立場でmが>>60でのn。
#以下 SageMathコード
,var m,n,l,k,q,r,c
T2 = (n-1-l) + (n-q)*(m-1-k)
T1 = T2 - (r-k)
#mが奇数の場合:
Q1 = (sum(sum(binomial(T1.subs({n:m+1,q:k,r:k+l}),c-1), l,k+1,m-k-2), k,0,(m-1)/2-1)
+ sum(sum(binomial(T2.subs({n:m+1,q:k+1,r:k+l-m}),c-1), k,m-1-l,l-1), l,(m+1)/2,m-1)
+ sum(binomial(T2.subs({n:m+1,l:m,q:k+1,r:k}),c-1), k,0,m-2)
).subs({m:n,c:2}).simplify_full().factor()
#mが偶数の場合:
Q2 = (sum(sum(binomial(T1.subs({n:m+1,q:k,r:k+l}),c-1), l,k+1,m-k-2), k,0,m/2-2)
+ sum(sum(binomial(T2.subs({n:m+1,q:k+1,r:k+l-m}),c-1), k,m-1-l,l-1), l,m/2,m-1)
+ sum(binomial(T2.subs({n:m+1,l:m,q:k+1,r:k}),c-1), k,0,m-2)
).subs({m:n,c:2}).simplify_full().factor()
def Q1st(x):
return (Q1 if mod(x,2) == 1 else Q2).subs({n:x})

続く
0198132人目の素数さん
垢版 |
2018/10/28(日) 20:36:18.50ID:x624ZJMX
>>197
続き

部屋がm×(m-1) (n=m-1) のとき。
(m-1)l>(n-1)k ⇔ 1≦l≦m-2 かつ 0≦k≦l。
(nk+l)/m = k + (l-k)/m より q=k,r=l-k。
r>k (l>2k)とr≦k (l≦2k)とに分けるように場合分けをする:
@0≦k≦[(m-3)/2], 2k+1≦l≦m-2 のとき r>k、
A1≦k≦[(m-3)/2], k≦l≦2k または B[(m-1)/2]≦k≦m-2, k≦l≦m-2 のとき r≦k。

m=7のとき
×@@@@@
×AA@@@
××AAA@
×××BBB
××××BB
×××××B
××××××

m=8のとき
×@@@@@@
×AA@@@@
××AAA@@
×××BBBB
××××BBB
×××××BB
××××××B
×××××××

後はΣの計算。>>60に合わせるとP君がA君の立場でmが>>60でのn+1。
#mが偶数の場合:
P1 = (sum(sum(binomial(T1.subs({n:m-1,q:k,r:l-k}),c-1), l,2*k+1,m-2), k,0,m/2-2)
+ sum(sum(binomial(T2.subs({n:m-1,q:k,r:l-k}),c-1), l,k,2*k), k,1,m/2-2)
+ sum(sum(binomial(T2.subs({n:m-1,q:k,r:l-k}),c-1), l,k,m-2), k,m/2-1,m-2)
).subs({m:n+1,c:2}).simplify_full().factor()
#mが奇数の場合:
P2 = (sum(sum(binomial(T1.subs({n:m-1,q:k,r:l-k}),c-1), l,2*k+1,m-2), k,0,(m-3)/2)
+ sum(sum(binomial(T2.subs({n:m-1,q:k,r:l-k}),c-1), l,k,2*k), k,1,(m-3)/2)
+ sum(sum(binomial(T2.subs({n:m-1,q:k,r:l-k}),c-1), l,k,m-2), k,(m-1)/2,m-2)
).subs({m:n+1,c:2}).simplify_full().factor()
def P1st(x):
return (P1 if mod(x,2) == 1 else P2).subs(n=x)

以上、整理して少し異なったけど>>161の導出でした。
0199132人目の素数さん
垢版 |
2018/10/28(日) 20:51:31.12ID:aWEG2qvY
>>198
P1 == 1/24*(6*n^3 + 20*n^2 - n - 27)*(n - 1) # nが奇数のとき
P2 == 1/4*n^4 + 7/12*n^3 - 7/8*n^2 - 13/12*n + 1 # nが偶数のとき
Q1 == 1/24*(6*n^2 + 10*n - 3)*(n + 1)*(n - 1) # nが奇数のとき
Q2 == 1/24*(6*n^2 - 2*n - 5)*(n + 2)*n # nが偶数のとき

それだけ前置きやってkを含めた式が作れないのですか?
■ このスレッドは過去ログ倉庫に格納されています