hdu 4576 概率dp

Michael has a telecontrol robot. One day he put the robot on a loop with n cells. The cells are numbered from 1 to n clockwise. 
 



At first the robot is in cell 1. Then Michael uses a remote control to send m commands to the robot. A command will make the robot walk some distance. Unfortunately the direction part on the remote control is broken, so for every command the robot will chose a direction(clockwise or anticlockwise) randomly with equal possibility, and then walk w cells forward. 
Michael wants to know the possibility of the robot stopping in the cell that cell number >= l and <= r after m commands. 

 

Input

There are multiple test cases. 
Each test case contains several lines. 
The first line contains four integers: above mentioned n(1≤n≤200) ,m(0≤m≤1,000,000),l,r(1≤l≤r≤n). 
Then m lines follow, each representing a command. A command is a integer w(1≤w≤100) representing the cell length the robot will walk for this command.   
The input end with n=0,m=0,l=0,r=0. You should not process this test case. 

 

Output

For each test case in the input, you should output a line with the expected possibility. Output should be round to 4 digits after decimal points.

 

Sample Input


 

3 1 1 2 1 5 2 4 4 1 2 0 0 0 0

 

Sample Output


 

0.5000 0.2500

 

 每個點都會順時針,逆時針的走,所以概率會一分爲二。 如:初始的1點概率爲1,走一步 那麼 n點和2點的概率都爲1/2

用dp[i][j]來表示在第i步時點j的概率是多少. 由於每個點的概率只與上一次的狀態有關,我們只需要兩行就夠了.

 

#include <queue>
#include <cstdio>
#include <set>
#include <string>
#include <stack>
#include <cmath>
#include <climits>
#include <map>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <stdio.h>
#include <ctype.h>
#define  LL long long
#define  ULL unsigned long long
#define mod 1000000007
#define INF 0x7ffffff
#define mem(a,b) memset(a,b,sizeof(a))
#define MODD(a,b) (((a%b)+b)%b)
#define maxn 1000005
using namespace std;
double dp[2][205];
int n,m;
int main()
{
    int l,r;
    while(~scanf("%d%d%d%d",&n,&m,&l,&r) &&(n + m + l + r)){
      mem(dp,0);
      dp[0][1] = 1.0;
      int cur = 0;
      while(m--){
        int x;
        scanf("%d",&x);
        cur ^= 1;//下一個狀態
        x = x % n;
        for(int i = 1; i <= n; i++){
          dp[cur][i] = dp[cur^1][i+x>n ? i+x-n : i+x] * 0.5 + dp[cur^1][i-x<1 ? i-x+n : i-x] * 0.5;//該狀態等於上一狀態的能到改點概率的和
        }

      }
      double ans = 0.0;
      for(int i = l; i <= r; i++){
        ans += dp[cur][i] * 1.0;
      }
      printf("%.4lf\n",ans);
    }


    return 0;

}

 

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