SRM727Hard

题意

\(B\) 只熊和 \(H\) 个人。攻击 \(T\) 次,每次随机从没死的怪中选出一个,扣一滴血,血量为 \(0\) 就死。每头熊 \(2\) 滴血,每个人 \(1\) 滴血。
\(T\) 次攻击后 \(b\ \times\ h\ \times\ (b\ +\ h)\) 的期望是多少。\(b\) 表示没死的熊的数量,\(h\) 表示没死的人的数量。

\(1\ \leq\ H,\ B\ \leq\ 2000,\ 0\ \leq\ T\ \leq\ 2B\ +\ H\)

做法1

\(E(b\ \times\ h\ \times\ (b\ +\ h))\ =\ E(b^2\ h\ +\ b\ h^2)\ =\ E(b^2\ h)\ +\ E(b\ h^2)\)
由于 \(b\)\(h\) 不是独立的,不能将 \(E(b^2\ h)\) 拆成 \(E(b^2)\ E(h)\)
\(P(x,\ y,\ z)\) 表示还剩下 \(x\) 个两血怪,\(y\) 个一血怪,\(z\) 个人的概率是多少。
所求即为 \(\sum_{x,\ y,\ z}\ P(x,\ y,\ z)\ ((x\ +\ y\ -\ z)\ z^2\ +\ (x +\ y\ -\ z)^2\ z)\ =\ \sum_{x,\ y,\ z}\ P(x,\ y,\ z)\ ((x\ +\ y)^2\ z\ -\ (x\ +\ y)\ z^2)\)
我们令 \(E(x,\ y,\ 0)\ =\ \sum_{z}\ P(x,\ y,\ z)\ z,\ E(x,\ y,\ 1)\ =\ \sum_{z}\ P(x,\ y,\ z)\ z^2\),发现 \(E(x,\ y,\ 0/1)\) 可以 \(O(1)\) 转移。
总复杂度 \(O(n^2)\)

代码

#include <bits/stdc++.h>

using namespace std;

const int mod = 1e9 + 7;

struct DoubleLive {
	int findEV(int B, int H, int T) {
		auto inv = [&](int x) {
			int y = 1, n = mod - 2;
			while(n) {
				if(n & 1) y = (long long) y * x % mod;
				x = (long long) x * x % mod;
				n >>= 1;
			}
			return y;
		};

		vector<int> Mu(B + H + 1);
		for (int i = 1; i < Mu.size(); ++i) Mu[i] = inv(i);
		vector<vector<array<int, 2> > > E(B + 1);
		E[B] = vector<array<int, 2> >(B + H + 1, array<int, 2>{0, 0});
		E[B][H] = array<int, 2>{H, H * H};
		int ans = 0;
		for (int x = B; ~x; --x) {
			if(x) E[x - 1] = vector<array<int, 2> >(B + H + 1, array<int, 2>{0, 0});
			for (int y = B + H; ~y; --y) {
				int mu = Mu[x + y];
				if(y) {
					E[x][y - 1][0] = ((long long) E[x][y][0] * (y - 1) % mod * mu + E[x][y - 1][0]) % mod;
					E[x][y - 1][1] = ((long long) E[x][y][0] * mu + (long long) E[x][y][1] * (y - 2) % mod * mu + E[x][y - 1][1]) % mod;
				}
				if(x && y + 1 <= B + H) {
					for (int i = 0; i < 2; ++i) E[x - 1][y + 1][i] = ((long long) E[x][y][i] * x % mod * mu + E[x - 1][y + 1][i]) % mod;
				}
				if(2 * x + y + T == 2 * B + H) {
					ans = ((long long) -(x + y) * E[x][y][1] + (long long) (x + y) * (x + y) * E[x][y][0] + ans) % mod;
				}
			}
			E[x].clear();
		}
		return (ans + mod) % mod;
	}
};
posted @ 2018-10-10 11:21  King_George  阅读(167)  评论(0编辑  收藏  举报