D T4 飞行棋
题面
https://ac.nowcoder.com/acm/contest/7612/D
思路
数学期望题。
维护一个 数组,
代表从
到
的期望回合数。
通过列多元方程组可以得到 时
。 (这点数学基本功要有吧······)
然后就是一个递推的过程,要注意抛出 时即
到
时无需计算回合数,剩下的均要一个回合。
细节看代码注释
代码
#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <string>
#include <queue>
#include <stack>
#include <vector>
#include <set>
#include <map>
using std::cin;using std::cout;using std::cerr;using std::endl;
#define rep(i,a,b) for(int i = a;i <= b;++i)
#define per(i,a,b) for(int i = a;i >= b;--i)
const int mmax = 1e5;
int T,n;
double d,dp[mmax + 10],sum[mmax + 10];
int main(){
std::ios::sync_with_stdio(0);
cin.tie(0);
cin>>T;
while(T--){
cin>>n>>d;
int t = d;
rep(i,1,t - 1){
dp[i] = t - 1;
sum[i] = sum[i - 1] + dp[i]; //前缀和维护,降低复杂度
}
dp[t] = dp[t - 1] + 1 / d;
sum[t] = sum[t - 1] + dp[t];
rep(i,d + 1,n){
dp[i] = (sum[i - 1] - sum[i - t] + d - 1) / d + dp[i - t] / t;
//抛出的k的概率为 1 / d,
//k < d 时到达终点的期望贡献为(1 + dp[i - k]) / d。
//k = d 时到达终点的期望贡献为dp[i - k]。
sum[i] = sum[i - 1] + dp[i];
}
printf("%.2f\n",dp[n]);
}
return 0;
} 
京公网安备 11010502036488号