抄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; }
|
|
常用链接
随笔分类
Links
搜索
最新评论
|
|