HDU 4405 Aeroplane chess

HDU 4405 Aeroplane chess_第1张图片


置骰子的的概率DP。

我用grid [ i ] 表示 i 可以 直接飞到的位置。 prob [ i ]表示从 i 开始 到终点置骰子次数的期望。然后直接概率DP。

原始的递推式不难想,后六格每一个的期望乘上六分之一,再加上多置的一次骰子。因为置一次之后,移动到后六格的概率是相等的。

f[n]=( f[n+1]+ f [n+2] + f [n+3] + f [n+4]  + f [n+5] + f [n+ 6]  )/6   +1  ;

现在就是改进一下,初始化 grid 数组之后 ,把f [ n+ i ] 改成 f [  grid[n+i]  ] 就行了。

刚开始是用的记忆化搜索,从起点向终点递归。然后很自然的栈溢出了。

然后改成从终点向起点DP,就过了。代码如下。

int n,m;
int grid[100009];
double prob[100009];
int xi,yi;
void DPR(void);

int main(void)
{

	//读取数据
	while(cin>>n>>m){
		if(m+n==0) break;
		for(int i=0;i<=n+7;i++){//初始化 grid 和 prob;
			grid[i]=i; prob[i]=0.0;
		}
		
		
		for(int i=0;i<m;i++){
			scanf("%d%d",&xi,&yi);
			grid[xi]=yi;//记录可以飞到的位置
		}
		
		//初始化grid :连续直接飞行,最终可以到达的位置,
for(int i=0;i<=n;i++){int next=i;while(grid[next]!=next) {next=grid[next];}grid[i]=next;}DPR();//调用DPprintf("%.4f\n",prob[0]);//输出结果}return 0;}void DPR(void){//DPfor(int cur=n-1;cur>=0;cur--){//从终点向起点DPprob[cur]=1.0;for(int i=1;i<=6;i++){prob[cur]+=prob[grid[cur+i]]/6; //递推式} }}



你可能感兴趣的:(dp,概率DP)