您的位置:首页 > 其它

HDU 4050 wolf5x 概率dp 难度:1

2015-05-12 20:07 323 查看
http://acm.hdu.edu.cn/showproblem.php?pid=4050

题意:

现在主角站在0处,需要到达大于n的位置

主角要进入的格子有三种状态:

0. 不能进入

1. 能进入左脚,下一步出右脚

2. 能进入右脚,下一步出左脚

3. 两只脚都能进入,而且下一步迈出左右脚都可.

也就是说,如果只有1,2种状态的格子,那么主角只能重复左脚-右脚-左脚...或者右脚-左脚-右脚

但是有了状态为3的格子,就能够左脚-左脚-左脚这样走路

设e[i][sta]为主角在编号为i的方格状态为sta的概率,sta为1,2,3,分别代表踏入的是下一步右脚,下一步左脚,两只脚都可以的格子

并设kp1[i+a][i+j]从i+a开始到i+j-1右脚无法踏入的概率,kp2[i+a][i+j]从i+a开始到i+j-1左脚无法踏入的概率,kp3[i+a][i+j]为两只脚都无法踏入概率,

则:
e[i][1]+=(e[i+j][2]+1)*kp1*p2[i+j]+(e[i+j][3]+1)*kp1*p3[i+j];
e[i][2]+=(e[i+j][1]+1)*kp2*p1[i+j]+(e[i+j][3]+1)*kp2*p3[i+j];
e[i][3]+=(e[i+j][1]+1)*kp3*p1[i+j]+(e[i+j][2]+1)*kp3*p2[i+j]+(e[i+j][3]+1)*kp3*p3[i+j];

明显e[0][3]为答案

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <queue>
using namespace std;
const int maxn=2e3+1;
const double eps=1e-9;
int n,a,b;
double p0[maxn],p1[maxn],p2[maxn],p3[maxn];
double e[maxn][4];
void calc(){
for(int i=n;i>=0;i--){
memset(e[i],0, sizeof e[i]);
double kp1=1,kp2=1,kp3=1;
for(int j=a;j<=b;j++){
if(i+j>n){
e[i][1]+=kp1;
e[i][2]+=kp2;
e[i][3]+=kp3;
break;
}
e[i][1]+=(e[i+j][2]+1)*kp1*p2[i+j]+(e[i+j][3]+1)*kp1*p3[i+j];
e[i][2]+=(e[i+j][1]+1)*kp2*p1[i+j]+(e[i+j][3]+1)*kp2*p3[i+j];
e[i][3]+=(e[i+j][1]+1)*kp3*p1[i+j]+(e[i+j][2]+1)*kp3*p2[i+j]+(e[i+j][3]+1)*kp3*p3[i+j];
kp1*=(p0[i+j]+p1[i+j]);
kp2*=(p0[i+j]+p2[i+j]);
kp3*=(p0[i+j]);
}

}
}

int dcmp(double a,double b){
if(fabs(a-b)<=eps)return 0;
return a>b?1:-1;
}
int main(){
int T;
scanf("%d",&T);
while(T--&&scanf("%d%d%d",&n,&a,&b)==3){
for(int i=1;i<=n;i++){
scanf("%lf%lf%lf%lf",p0+i,p1+i,p2+i,p3+i);
}
calc();
printf("%.8f\n",e[0][3]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: