【hdu4576】【期望Dp】Robot

【hdu4576】Robot

题目大意

Michael有一个遥控机器人。一天,他把机器人放在一个有N个单元格的环上。单元格从1到n按顺时针顺序编号。
一开始,机器人在1号单元。然后Michael使用遥控器将M命令发送给机器人。命令会让机器人走一段距离。不幸的是,遥控器控制方向的部件坏了,所以发射每一个命令后,机器人会以平等的可能性随机选择一个方向(顺时针或逆时针),然后向前走W个单元格。Michael想要知道在第m条命令后,机器人停在单元格区间[L,R]之间的概率。
【输入格式】
有多组测试数据。
每组测试数据包含若干行。
当n,m,l,r都为0时结束。
第一行包含四个整数:上面提到的n(1≤n≤200)、m(0≤m≤1000000),L,R(1≤L≤R≤n)。接下来m行,每行代表一个命令。一个命令是一个整数W(1≤W≤100)表示机器人所走的单元格的长度。
【输出格式】
对于每组数据,输出答案,结果保留4位小数。
【输入样例】
3 1 1 2
1
5 2 4 4
1
2
0 0 0 0
【输出样例】
0.5000
0.2500

思路

我们看一下这题问的就是到达这个区间的期望
所以我们可以用期望Dp
首先,我们把点标号为0~n-1
而对于每个指令,它有一半的几率向左走,还有一半的几率向右走
所以我们可以把可以到达的那个点的几率加上0.5*f【i】(i为当前位置)
这就是一个期望Dp
但是m≤1000000,需要开200*1000000的数组(开不下!!!)
我们选择用滚动数组

代码

#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <iostream>
#define N 220
using namespace std;
double f[2][N];
int n,m,l,r,x;
int main(){
    while(scanf("%d%d%d%d",&n,&m,&l,&r)){
        if(n==0&&m==0&&l==0&&r==0)break;
        for(int i=0;i<=n;++i)f[0][i]=0;
        f[0][0]=1;
        int cur=0;
        for(int ij=1;ij<=m;ij++){
            scanf("%d",&x);
            for(int i=0;i<n;++i)f[cur^1][i]=0;
            for(int i=0;i<n;++i){
                if(f[cur][i]==0)continue;
                f[cur^1][((i-x)%n+n)%n]+=0.5*f[cur][i];
                f[cur^1][(i+x)%n]+=0.5*f[cur][i];
            }
            cur^=1;
        }
        double ans=0;
        for(int i=l-1;i<r;++i)ans+=f[cur][i];
        printf("%.4lf\n",ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值