Robot HDU - 4576 dp+滚动数组

传送门

题目大意:有一个环,有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;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值