您的位置:首页 > 其它

poj 3756 Chess Game 模拟型概率dp

2014-07-20 09:23 197 查看
这题太对我胃口了,以前一直在想概率dp可以让计算机去模拟过程求解,但之前的题都数据太大无法模拟,这道题数据小+精度要求低+成环无规律+有一些终点,正解应该是高斯消元,但是暴力模拟很好切过

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
#include <queue>
#define ll long long
using namespace std;
const ll inf =1e17;
const double zr = 1.0/6.0;

int map[105];
int zou[105];
double dp[205][105];
int n;

int cal(int pos)
{
while(true)
if (pos < 0) pos = -pos;
else if (pos > n) pos = n + n - pos;
else return pos;
}

int main()
{
int i,j,k,t;
int ta,tb;
scanf("%d",&n);
scanf("%d",&t);
for(i=1;i<=t;i++)
{
scanf("%d%d",&ta,&tb);
map[ta]=1;
zou[ta]=tb;
}
scanf("%d",&t);
for(i=1;i<=t;i++)
{
scanf("%d%d",&ta,&tb);
map[ta]=1;
zou[ta]=-tb;
}
scanf("%d",&t);
for(i=1;i<=t;i++)
{
scanf("%d",&ta);
map[ta]=2;
}
dp[0][0]=1.0;
double ans=0;
for(i=1;i<=200;i++)
{
for(j=0;j<n;j++)
{
if(dp[i-1][j]!=0)
{
for(k=1;k<=6;k++)
{
if(map[cal(j+k)]==0)
dp[i][cal(j+k)]+=dp[i-1][j]*zr;
else if(map[cal(j+k)]==2)
dp[i+1][cal(j+k)]+=dp[i-1][j]*zr;
else
dp[i][cal(cal(j+k)+zou[cal(j+k)])]+=dp[i-1][j]*zr;
}
}
}
ans+=i*dp[i]
;
}
if(ans==0)
printf("Impossible\n");
else
printf("%.2lf\n",ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: