抄iSea标程的    V5
/**/ /*
    题意:5个敌人,各自有hp(1<=hp<=5) 现随机扔一个球给一个人,然后这个人的hp就会-1
    随后,这个球会随机扔给距离不超过D的另外一个人(不能是自己),收到球的敌人hp-1
    当hp=0时死掉
    问每个敌人死掉的概率

    6维
    dp[hp[0]][hp[1]][hp[2]][hp[3]][hp[4]][cur]表示当前球在cur处,每个人的对应的血为hp[i]时的概率
    记忆化搜索
    
    一开始时每个人的概率就是0.2了
    答案就是只要血为0时的概率累加
 
  用bfs状态比较大
  记忆化搜索比较好
*/

#include
< cstdio >
#include
< iostream >
#include
< cstring >
#include
< cmath >
#include
< algorithm >

using   namespace  std;

struct  Point
{
    
double x,y;
}
;

double  dp[ 6 ][ 6 ][ 6 ][ 6 ][ 6 ][ 6 ];
double  ans[ 6 ];
int  N,D,hp[ 6 ],_hp[ 6 ],totHp;
Point pt[
6 ];
bool  can[ 6 ][ 6 ];

bool  chk(Point  & a,Point  & b)
{
    
return (a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y) <= D*D;
}


double  cal( int   * _hp, int  cur)
{
    
double &ans = dp[_hp[0]][_hp[1]][_hp[2]][_hp[3]][_hp[4]][cur];


    
if(ans >= 0.0)    return ans;

    ans 
= 0.0;

    
int _totHp = 0;
    
for(int i = 0; i<5;i++)
        _totHp 
+= _hp[i];

    
if(_totHp + N + 1 < totHp) return 0.0;
    
if(_hp[cur] + 1 > hp[cur])return 0.0;
    
    
for(int i=0;i<5;i++)
    
{
        
if(can[i][cur])
        
{
            
int cnt = 0;
            
int _hp2[6];
            
for(int j = 0;j<5;j++)
            
{
                _hp2[j] 
= _hp[j];
                
if(j==cur)++_hp2[j];
                
if(_hp2[j] && can[i][j])cnt++;//can[i][j]
            }

            ans 
+= cal(_hp2,i)/cnt;    
        }

    }

    
return ans;
}


int  main()
{
#ifdef ONLINE_JUDGE
#else
    freopen(
"in","r",stdin);
#endif
    
while~scanf("%d%d" ,&N,&D) )
    
{
        memset(can,
0,sizeof(can));
        
for(int i = 0; i<5; i++)
        
{
            scanf(
"%lf%lf",&pt[i].x,&pt[i].y);
            
for(int j = 0;j<i;j++)
            
{
                can[i][j] 
= can[j][i] = chk(pt[i],pt[j]);
            }

        }


        totHp 
= 0;
        
for(int i=0;i<5;i++)
        
{
            scanf(
"%d",&hp[i]);
            totHp 
+= hp[i];
        }


        
for(_hp[0]=0;_hp[0]<=hp[0];_hp[0]++)
        
for(_hp[1]=0;_hp[1]<=hp[1];_hp[1]++)
        
for(_hp[2]=0;_hp[2]<=hp[2];_hp[2]++)
        
for(_hp[3]=0;_hp[3]<=hp[3];_hp[3]++)
        
for(_hp[4]=0;_hp[4]<=hp[4];_hp[4]++)
            
for(int i = 0; i<5;i++)
                dp[_hp[
0]][_hp[1]][_hp[2]][_hp[3]][_hp[4]][i]  = -1.0;

        dp[hp[
0]-1][hp[1]][hp[2]][hp[3]][hp[4]][0= 0.2;
        dp[hp[
0]][hp[1]-1][hp[2]][hp[3]][hp[4]][1= 0.2;
        dp[hp[
0]][hp[1]][hp[2]-1][hp[3]][hp[4]][2= 0.2;
        dp[hp[
0]][hp[1]][hp[2]][hp[3]-1][hp[4]][3= 0.2;
        dp[hp[
0]][hp[1]][hp[2]][hp[3]][hp[4]-1][4= 0.2;
        
        memset(ans,
0,sizeof(ans));
        
for(_hp[0]=0;_hp[0]<=hp[0];_hp[0]++)
        
for(_hp[1]=0;_hp[1]<=hp[1];_hp[1]++)
        
for(_hp[2]=0;_hp[2]<=hp[2];_hp[2]++)
        
for(_hp[3]=0;_hp[3]<=hp[3];_hp[3]++)
        
for(_hp[4]=0;_hp[4]<=hp[4];_hp[4]++)
            
for(int i = 0;i<5;i++)
            
{
                
double t = cal(_hp,i);
                
if(_hp[i]==0)ans[i] += t;//_hp[i]=0时概率就累加
            }


        
for(int i = 0;i<5;i++)
        
{
            
if(i)putchar(' ');
            printf(
"%.3f",ans[i]);
        }

        puts(
"");
    }
        
    
return 0;
}