zoukankan      html  css  js  c++  java
  • hdu 4576 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.
     
    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
     
    题目翻译:
     

    迈克尔有一个远程遥控机器人。有一天,他把机器人放在一个有n个格子的环上。单元顺时针编号为1到n。


    起初机器人在单元格1中。迈克尔使用遥控器向机器人发送m个命令。命令将使机器人走一段距离。不幸的是,遥控器上的方向部分被毁坏,因此对于每个命令,机器人将以相同的可能性随机选择方向(顺时针或逆时针),然后向前走动w单元。
    迈克尔想要知道机器人在m个指令后在单元格 l ~ r 中停止的可能性。

    输入
    有多个测试用例。
    每个测试用例包含几行。
    第一行包含四个整数:上述n(1≤n≤200),m(0≤m≤1,000,000),l,r(1≤l≤r≤n)。
    然后是m行,每行代表一个命令。命令是整数w(1≤w≤100),表示机器人为此命令行走的单元长度。
    输入端的n = 0,m = 0,l = 0,r = 0。您不应该处理此测试用例。

    输出
    对于输入中的每个测试用例,您应在一行中输出具有预期可能性。小数点后应保留四位数。

    分析

    推荐学长的blog:【概率期望动态规划】

    part 1 状态

    状态明显跟上一次的情况有关,与单元格编号有关:

    f[步数编号][单元格] = 概率

    记得初始化,最初的时候,单元格1概率是1,其余为0

    emmm,既然至于上一次有关,那么可以滚动啊

    part 2 转移

    刷表法 or 填表法

    学长说的很清楚了,当前单元格要么来自i - w,要么来自i + w。

    part 3 注意事项

    关于w万一大于n:这个好办,取余

    关于初始化:记得还有这回事

    代码

     1 /***********************
     2 User:Mandy.H.Y 
     3 Language:c++
     4 Problem:hdu4576
     5 Algorithm:
     6 ************************/
     7 
     8 //一个概率 + 环形的背包? 
     9 
    10 #include<cstdio>
    11 #include<cmath>
    12 #include<iomanip>
    13 #include<algorithm>
    14 #include<cstring>
    15 
    16 using namespace std;
    17 
    18 const int maxn = 205;
    19 const int maxm = 1e6 + 5;
    20 
    21 int n,m,l,r;
    22 double f[2][maxn],ans = 0;
    23 
    24 template<class T>inline void read(T &x){
    25     x = 0;bool flag = 0;char ch = getchar();
    26     while(!isdigit(ch)) flag |= ch == '-',ch = getchar();
    27     while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48),ch = getchar();
    28     if(flag) x = -x;
    29 }
    30 
    31 template<class T>void putch(const T x){
    32     if(x > 9) putch(x / 10);
    33     putchar(x % 10 | 48);
    34 }
    35 
    36 template<class T>void put(const T x){
    37     if(x < 0) putchar('-'),putch(-x);
    38     else putch(x);
    39 }
    40 
    41 void file(){
    42     freopen("4576.in","r",stdin);
    43     freopen("4576.out","w",stdout);
    44 }
    45 
    46 int get(int x){
    47     if(x < 1) return x + n;
    48     if(x > n) return x - n;
    49     return x;
    50 }
    51 
    52 void work(){
    53     memset(f,0,sizeof(f));//记得清零 
    54     f[0][1] = 1;
    55     int cur = 1;ans = 0; 
    56     for(int i = 1;i <= m; ++ i) {
    57         int w;read(w);w %= n;//要对n取模,防止溢出 
    58         for(int i = 1;i <= n; ++ i){
    59             f[cur][i] = f[cur ^ 1][get(i - w)] * 0.5;
    60             f[cur][i] += f[cur ^ 1][get(i + w)] * 0.5;
    61         }
    62         cur ^= 1;
    63     }
    64     cur ^= 1;
    65     for(int i = l;i <= r; ++ i) ans += f[cur][i];
    66 }
    67 
    68 int main(){
    69     
    70 //    file();
    71 
    72     while(scanf("%d%d%d%d",&n,&m,&l,&r)){
    73         if((!n) && (!m) && (!l) && (!r)) break;
    74         work();
    75         printf("%.4lf
    ",ans);
    76     }
    77     
    78     return 0;
    79 }
    View Code
    非做顽石不可,哪管他敬仰暗唾
  • 相关阅读:
    springboot 搭建druid数据监控
    spring-boot编写简易mvc
    解决rabbitmq 开启启动报错
    intelij idea 使用maven打包报错 Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.1
    php foreach循环引用的问题
    手把手编写hyperf JsonRpc demo
    centos8配置nfs教程本机系统mac
    Java基础的练习题
    Java——循环
    Java——数组
  • 原文地址:https://www.cnblogs.com/Mandy-H-Y/p/11402638.html
Copyright © 2011-2022 走看看