题目大意:给出n,m,l,r表示有一个由n个位置组成的环,序号按照顺时针来是1~n。起始位置默认为1,现在走m步,给出m步的大小,对于每一步来说可以选择顺时针和逆时针移动,问说最后落在l~r这片区间的概率。
解题思路:dp[i][j]表示说第i步移动到j的概率,注意是概率,因为基数很大,所以不可能直接计算出来可能的种类。然后dp[i][j]的话,数组太大,所以用滚动数组优化空间。
#include <stdio.h>
#include <string.h>
const int N = 205;
double dp[2][N];
int n, m, l, r, t, w;
int main () {
while (scanf("%d%d%d%d", &n, &m, &l, &r) == 4 && n + m + l + r) {
memset(dp, 0, sizeof(dp));
dp[0][0] = 1;
for (int i = 1; i <= m; i++) {
scanf("%d", &w);
int now = i&1;
int pre = !now;
for (int j = 0; j < n; j++) {
if (dp[pre][j] > 0) {
double val = dp[pre][j]*0.5;
dp[now][(j+w+n)%n] += val;
dp[now][(j-w+n)%n] += val;
}
dp[pre][j] = 0;
}
}
double ans = 0;
for (int i = l - 1; i < r; i++)
ans += dp[m&1][i];
printf("%.4lf\n", ans);
}
return 0;
}