CF838D Airplane Arrangements

一架飛機有\(n\)個座位排成一列,有\(m\)名乘客\((m\leq n)\)依次上飛機。
乘客會選擇一個目標座位(兩人可以選同一個目標座位),然後選擇從前門或者後門上飛機,上飛機後,他們會走到自己的目標座位,如果目標座位已經有人坐了,他們會繼續往前走,在走到第一個空位後坐下。如果走到最後還沒有找到座位,這名乘客就會生氣。
問有多少種登機方案能讓所有乘客都不生氣。兩個登機方案不同當且僅當第\(i\)位乘客的目標座位或上飛機走的門不同。


這個問題有一個巧妙的轉化:現在不是一排\(n\)個座位了,而是一個\(n+1\)個座位的環。這樣的話原問題的走到最後沒有位置就變成了新問題的走到了第\(n+1\)個位置。爲什麼可以這麼轉化呢?因爲如果定義新問題的不合法方案爲有人坐了第\(n+1\)個座位,那麼原問題的合法方案是能和新問題的合法方案一一對應,即原問題的合法方案在新問題中一定也合法,新問題的合法方案在原問題中也一定合法。也就是說,兩個問題的合法方案數是一樣的,那麼我們只需要計算新問題的合法方案數即可。

注意到現在是一個環,那麼每個座位都是沒有區別的。所以每個座位被坐的概率應當是一樣的,我們設它爲\(p\)。而最後一定有\(m\)個座位被坐,那麼就有\(p(n+1)=m\),即\(p=\frac{m}{n+1}\)。那麼第\(n+1\)個座位不被坐的概率就是\(\frac{n+1-m}{n+1}\)。總方案數是\(2^m(n+1)^m\),兩個式子相乘就是答案。

#include<bits/stdc++.h>
using namespace std;
const int mod = 1e9+7;
int n, m;
inline int fpow(int a, int b, int ans = 1){
	for(; b; b >>= 1, a = 1ll*a*a%mod)if(b&1)ans = 1ll*ans*a%mod;
	return ans;
}
int main(){
	cin >> n >> m;
	int p = 1ll*(n+1-m)*fpow(n+1, mod-2)%mod;
	int tot = fpow(2*(n+1), m);
	printf("%lld", 1ll*p*tot%mod);
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章