STDU 2878 概率dp

Circle

Time Limit: 2000ms   Memory limit: 65536K  有疑問?點這裏^_^

題目描述

You have been given a circle from 0 to n - 1. If you are currently at x, you will move to (x - 1) mod n or (x + 1) mod n with equal probability. Now we want to know the expected number of steps you need to reach x from 0.

輸入

The first line contains one integer T — the number of test cases.
 
Each of the next T lines contains two integers n, x (0  ≤ x < n ≤ 1000) as we mention above.

輸出

For each test case. Print a single float number — the expected number of steps you need to reach x from 0. The figure is accurate to 4 decimal places.

示例輸入

3
3 2
5 4
10 5

示例輸出

2.0000
4.0000
25.0000

提示

 

來源

2014年山東省第五屆ACM大學生程序設計競賽

示例程序

分析:對於這種類型的概率題,直接迭代係數比較好!!
我們可以用dp[i]表示當前在i點到達x點的期望步數,那麼顯然dp[x]=0.同時 dp[0]即爲所求;
以x爲軸,左右兩邊同時迭代到0的時候就可得到方程:

dp[0]=A1[0]*dp[n-1]+B1[0]
dp[n-1]=A2[n-1]*dp[0]+B2[n-1]
(其中A1[0],A2[n-1],B1[0],B2[n-1]都是常數)
#include <iostream>
#include <stdio.h>
#include <string>
#include <string.h>
#include <algorithm>
using namespace std;
const int maxn=1100;

int n,x;
double A1[maxn],B1[maxn];
double A2[maxn],B2[maxn];


void solve() //迭代運算
{
    A1[x-1]=1.0/2,B1[x-1]=1.0;

    for(int i=x-2;i>=0;i--)  //最終 dp[0]=A1[0]*dp[(0-1+n)%n]+B1[0]
    {
      double tmp=1.0-0.5*A1[i+1];
      A1[i]=0.5/tmp;
      B1[i]=(1.0+0.5*B1[i+1])/tmp;
    }

    if(x==n-1)
    {
      A2[6]=0.0;
      B2[6]=0.0;
    }
    else
    {
      A2[x+1]=1.0/2,B2[x+1]=1.0;
      for(int i=(x+2)%n; i!=0;i=(i+1)%n)
      {
         double tmp=1.0-0.5*A2[i-1];
         A2[i]=0.5/tmp;
         B2[i]=(1.0+0.5*B2[i-1])/tmp;
      }
    }
    double ans=(A1[0]*B2[n-1]+B1[0])/(1-A1[0]*A2[n-1]);

    printf("%.4lf\n",ans);
}

int main()
{
   int T;
   scanf("%d",&T);
   while(T--)
   {
     scanf("%d%d",&n,&x);
     if( x==0 || n==1)
     {
       printf("0.0000\n");
       continue;
     }
     if(n==2)
     {
        printf("1.0000\n");
        continue;
     }

     solve();
   }
   return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章