首页 > 代码库 > [ACM] HDU 4576 Robot (概率DP,滚动数组)
[ACM] HDU 4576 Robot (概率DP,滚动数组)
Robot
Problem Description
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.
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.
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
Source
2013ACM-ICPC杭州赛区全国邀请赛
题意为有编号1-N的格子围城一个圈,一开始机器人站在1号格子,有M个命令,每个命令机器人走W格,可以顺时针也可以逆时针,问M个命令后,机器人站在格子[L,R] 的概率是多少.
想法大体为暴力计算出M个命令后,每个格子上机器人在的概率,那么 P[ L ] + P[ L+1] + P[ L+2] +............P[R] 即为所求
用dp[i][j] ,表示第i个命令后机器人站在j位置的概率
因为命令数m,0≤m≤1,000,000,不可能开出这么大的数组,又因为第i个命令后机器人所在位置的概率只与第i-1个命令后的机器人所在位置有关,所以可以用滚动数组,dp [2] [j]来表示。滚动数组要求当前状态只和前一个状态有关系,和更早之前的状态没关系,所以之前保存的数空间可以覆盖,重新利用,这样就可以降低空间复杂度,但时间复杂度不变。
滚动数组详解:http://blog.csdn.net/niushuai666/article/details/6677982
代码:
#include <iostream> #include <stdio.h> #include <iomanip> #include <string.h> using namespace std; double dp[2][210]; int main() { int n,m,l,r,cm; while(scanf("%d%d%d%d",&n,&m,&l,&r)!=EOF) { if(n==0&&m==0&&l==0&&r==0) break; int d=0; for(int i=1;i<n;i++) dp[d][i]=0; dp[0][0]=1; while(m--) { scanf("%d",&cm); for(int i=0;i<n;i++) dp[d^1][i]=0;//新状态下每个位置的概率都为0 for(int i=0;i<n;i++) { if(dp[d][i]==0)//加上这一句就不超时了 continue; dp[d^1][(i+cm)%n]+=0.5*dp[d][i]; dp[d^1][(i-cm+n)%n]+=0.5*dp[d][i]; } d^=1;//^1 就是加1或者减1交替进行 } double ans=0; for(int i=l-1;i<r;i++) ans+=dp[d][i]; cout<<setiosflags(ios::fixed)<<setprecision(4)<<ans<<endl; } return 0; }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。