题目链接: https://atcoder.jp/contests/abc189/tasks/abc189_f.
难点在于有返回0广场时,旋转轮子次数的期望值。
代码如下:
#include<iostream>
#include<cstdio>
using namespace std;
const int BUF = 100005;
int nCell, nMove, nBackCell;
int backCell[BUF];
void read() {
cin >> nCell >> nMove >> nBackCell;
for (int i = 0; i < nBackCell; ++i) {
cin >> backCell[i];
}
}
void work() {
bool isBackCell[BUF] = {
};
for (int i = 0; i < nBackCell; ++i) {
isBackCell[backCell[i]] = true;
}
double goBackP[BUF * 2], curGoBack = 0;
double ans[BUF * 2], curAns = 0;
for (int i = nCell; i < nCell + nMove; ++i) {
goBackP[i] = ans[i] = 0;
}
for (int i = nCell - 1; i >= 0; --i) {
if (isBackCell[i]) {
goBackP[i] = 1.0;
ans[i] = 0;
} else {
goBackP[i] = curGoBack;
ans[i] = curAns + 1;
}
curGoBack += (goBackP[i] - goBackP[i + nMove]) / nMove;
curAns += (ans[i] - ans[i + nMove]) / nMove;
if (curGoBack >= 1 - 1e-8) {
cout << -1 << endl;
return;
}
}
printf("%.10lf\n", ans[0] / (1 - goBackP[0]));
}
int main() {
read();
work();
return 0;
}