Robot HDU

来源:互联网 发布:淘宝店铺首页如何设置 编辑:程序博客网 时间:2024/05/19 20:59

传送门

题目大意:有一个环,有n个格子,编号为1~n;   一开始1的位置上有一个机器人,每次给他一个指令m,它移动m距离,但是它等可能的向左或者向右。求m条指令之后在l和r之间的可能性。

解题思路:这个题卡时间卡的非常紧,超时了两次。简直崩溃,但是题目本身不难。每读取一个指令,将数组内概率更新,每个位置都可能向前或者向后x,因此把自己的概率乘以0.5加给那个格子即可。但是每次都应该初始化为零,因为这个指令之后,自己格子原来的概率已经没有了,即上次没停留,只是执行到这一次时在这里的概率。因此还需要一个数组保存上次格子的概率。因为卡时间,所以用滚动时数组。


AC代码:

#include <iostream>#include <cstdio>#include <cstring>using namespace std;int main(){int n, m, l, r, x;double dp[2][205];while(scanf("%d%d%d%d", &n, &m, &l, &r) == 4 && n+m+l+r){memset(dp, 0, sizeof(dp));dp[0][1] = 1.0;bool k = 1;for(int i=0; i<m; i++){scanf("%d", &x);k = k ^ 1;//异或1,使k在1和0来回变换达到滚动的目的for(int j=1; j<=n; j++) dp[!k][j] = 0;//!k则是保存本次的概率。k是上次的概率for(int j=1; j<=n; j++){if(!dp[k][j]) continue;dp[!k][ (j+x-1)%n+1 ] += 0.5 * dp[k][j];dp[!k][ (j+n*100-x-1)%n+1 ] += 0.5 * dp[k][j];}}double ans = 0.0;for(int i=l; i<=r; i++) ans += dp[!k][i];printf("%.4f\n", ans);}return 0;}