JZOJ3871 [NOIP2014八校聯考第4場第1試10.19] 無聊的遊戲

Description
學校的運動會開始了,體能很菜的小可可沒報任何比賽項目,於是和同學們玩一個十分無聊的遊戲。
遊戲在一個由nn個方格組成的正方形棋盤上進行,首先在每個方格上均勻隨機地填入1到m之間的正整數(每個方格填的數均不同),然後小可可均勻隨機地選出k個1到m的數字(可能選的數不在棋盤上),把它們出現在棋盤上的方格塗黑,設有R行被整行塗黑,有C列被整列塗黑,小可可便可以得到2^(R+C)分。
現在小可可想知道他的期望得分是多少,你能幫助他嗎?
Input
第一行包含三個正整數n,m,k。
Output
僅一行包含一個實數,爲期望得分,如果答案>10^99,就輸出 1099,輸出被認爲正確當且僅當你的輸出與標準輸出的相對誤差不超過10-6。
Data Constraint
對於30%的數據,2≤n≤5,m≤10;
對於60%的數據,2≤n≤10,m≤200;
對於100%的數據,2≤n≤300, n
n≤m≤100000, n≤k≤m。
Solution
算法一:
m≤10,實際上 n≤3,於是可以暴力枚舉所有的填法和選法。
期望得分:30 分
算法二:
設行集合R和列集合C,|R| = r, |C| = c而這些行被塗黑的概率爲R,CPR,c\sum_{R,C}P_R,c
而答案還可以表示爲
i=0n\sum_{i=0}^ni=0nPr,c\sum_{i=0}^nP_r,c
這裏這個Pr,c也十分好求,爲在這裏插入圖片描述
這裏 t=n(r+c)-rc 爲整行、列填黑的格子個數。
時間複雜度O(n^2),期望得分100分
Code

#include <cstdio>

int n, m, k;
double ans;
double f[407], g[100007];

int main()
{
	ans = 0;
	scanf("%d%d%d", &n, &m, &k);
	f[0] = g[0] = 1;
	for (int i = 1; i <= n; ++ i) f[i] = f[i - 1] / i * (n - i + 1);
	for (int i = 1; i <= m; ++ i) g[i] = g[i - 1] / (m - i + 1) * (k - i + 1);
	for (int i = 0; i <= n; ++ i)
	{
		for (int j = 0; j <= n; ++ j)
		{
			int t = (i + j) * n - i * j;
			if (t > k) continue;
			ans += f[i] * f[j] * g[t];
		}
	}
	printf("%0.12f\n", (ans > 1e99) ? (1e99) : (ans));
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章