【BZOJ1867】[Noi1999]釘子和小球【DP】

【題目鏈接】

簡單DP。。

注意輸出不能有換行。

/* Think Thank Thunk */
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

typedef long long LL;

const int maxn = 55;

int n, m;
bool g[maxn][maxn];

inline LL gcd(LL a, LL b) {
	for(; b; b ^= a ^= b ^= a %= b);
	return a;
}

struct fra {
	LL u, d;

	fra(LL a = 0, LL b = 1) {
		u = a; d = b;
	}

	void sim() {
		LL t = gcd(u, d);
		u /= t; d /= t;
	}

	fra operator + (const fra &A) {
		LL t = gcd(d, A.d);
		fra res = fra(d / t * A.u + A.d / t * u, d / t * A.d);
		res.sim();
		return res;
	}

	fra operator * (const fra &A) {
		fra res = fra(u * A.u, d * A.d);
		res.sim();
		return res;
	}
} dp[maxn][maxn];

inline bool cread() {
	char ch = getchar();
	for(; ch == ' ' || ch == '\n' || ch == '\r'; ch = getchar());
	return ch == '*';
}

int main() {
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= n; i++) for(int j = 1; j <= i; j++) g[i][j] = cread();

	dp[1][1] = fra(1, 1);
	for(int i = 1; i <= n; i++) for(int j = 1; j <= i; j++)
		if(g[i][j]) dp[i + 1][j] = dp[i + 1][j] + dp[i][j] * fra(1, 2), dp[i + 1][j + 1] = dp[i + 1][j + 1] + dp[i][j] * fra(1, 2);
		else dp[i + 2][j + 1] = dp[i + 2][j + 1] + dp[i][j];

	printf("%lld/%lld", dp[n + 1][m + 1].u, dp[n + 1][m + 1].d);
	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章