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 |
评论