A分布 Player B Player A HH HT TT HH 1 1 2 HT 0 0 1 TT -1 0 0 B分布 Player B Player A HH HT TT HH 0 -1 -1 HT 1 0 0 TT 2 0 -1 A和B在此分布下进行20轮累计,求每轮分数的胜负概率。第一次做的时候以为A和B是独立的,分别计算他们得分的概率,再计算大小,结果第一轮的数据就卡住。然后想到了一个取巧的办法,把A和B的得分相减,得到一个新的分布,最后判断总分是否大于0。 随便说一句,我的代码风格向软件工程的标准又迈进了一步,这是人类的一小步,却是我的一大步。 #include <cstdio>#include <string> #define def 100 double p[7], s[2][200];int mx, mn; void ps (int c){ int i; double sum_w, sum_l, sum_t; sum_w = sum_l = sum_t = 0; for ( i = mn - 3; i <= mx + 3; i ++ ) { if ( i > def ) sum_w += s[0][i]; if ( i < def ) sum_l += s[0][i]; if ( i == def ) sum_t += s[0][i]; } printf ( "%5d%10.4f%%%9.4f%%%9.4f%%\n", c, sum_w * 100, sum_l * 100, sum_t * 100 );} void init (){ p[0] = 1.00 / 16, p[1] = 0, p[2] = 2.00 / 16, p[3] = 6.00 / 16; p[4] = 4.00 / 16, p[5] = 2.00 / 16, p[6] = 1.00 / 16; printf ( "Round A wins B wins Tie\n" );} void dp (){ int i, k, j; s[0][def] = 1.00; for ( i = 0; i < 20; i ++ ) { mx = def + 3 * i, mn = def - 3 * i; memset ( s[1], 0x00, sizeof (s[1]) ); for ( k = mn; k <= mx; k ++ ) { for ( j = -3; j <= 3; j ++ ) { s[1][k + j] += s[0][k] * p[j + 3]; } } memcpy ( s[0], s[1], sizeof (s[0]) ); ps (i + 1); }} int main (){ init (); dp (); return 0;} 2206053 2007-01-23 14:44:10 Accepted 1349 C++ 00:00.00 392K Crux.D

评论