HDU 4576 Robot

Robot

Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others)
Total Submission(s): 515    Accepted Submission(s): 178


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
 

Source
 

题意: 有N个数字,M个操作, 区间L, R。 然后问经过M个操作后落在[L, R]的概率。
思路: DP
dp[i][j]  表示第i次操作 落在第j个数字I的概率。
因为每次只需要需要取上一次的数据  所以只要开2个缓冲就好。 
但是坑爹题, 还是卡我这里。 
这个是超时的。其实跟AC的一模一样。 这样卡,没意思啊。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

//

const int V = 1000000 + 5;
const int MaxN = 200 + 5;
const int mod = 10000 + 7;
const __int64 INF = 0x7FFFFFFFFFFFFFFFLL;
const int inf = 0x7fffffff;
int n, m, l, r, num;
double dp[2][MaxN];
int main() {
    int i, j;
    while(scanf("%d%d%d%d", &n, &m, &l, &r)) {
        if(!n && !m && !l && !r)
            break;
        memset(dp, 0, sizeof(dp));
        dp[0][0] = 1;
        int a = 0;
        for(i = 1; i <= m; ++i) {
            a = i % 2;
            scanf("%d", &num);
            for(j = 0; j < n; ++j)
                dp[a][j] = 0;
            for(j = 0; j < n; ++j) {
                if(dp[a ^ 1][j] > 0) {
                    dp[a][(j + num) % n] += dp[a ^ 1][j] * 0.5;
                    dp[a][((j - num) % n + n) % n] += dp[a ^ 1][j] * 0.5;
                }
            }
        }
        double ans = 0.0;
        for(i = l - 1; i < r; ++i)
            ans += dp[a][i];
        printf("%.4lf\n", ans);
    }
}

这个是AC的。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

//

const int V = 1000000 + 5;
const int MaxN = 200 + 5;
const int mod = 10000 + 7;
const __int64 INF = 0x7FFFFFFFFFFFFFFFLL;
const int inf = 0x7fffffff;
int n, m, l, r, num;
double a[MaxN], b[MaxN];
int main() {
    int i, j;
    while(scanf("%d%d%d%d", &n, &m, &l, &r)) {
        if(n == 0 && m == 0 && l == 0 && r == 0)
            break;
        memset(a, 0, sizeof(a));
        memset(b, 0, sizeof(b));
        a[0] = 1;
        for(i = 1; i <= m; ++i) {
            scanf("%d", &num);
            for(j = 0; j < n; ++j) {
                if(a[j] > 0) {
                    b[(j + num) % n] += a[j] * 0.5;
                    b[((j - num) + n) % n] += a[j] * 0.5;
                }
            }
            for(j = 0; j < n; ++j) {
                a[j] = b[j];
                b[j] = 0;
            }
        }
        double ans = 0.0;
        for(i = l - 1; i < r; ++i)
            ans += a[i];
        printf("%.4lf\n", ans);
    }
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值