题面传送门

期望真 nm 有意思,所以蒟蒻又来颓期望辣

先特判掉 \(P_0=0\) 的情况,下面假设 \(P_0\ne 0\)。

首先注意到我们每次将加特林对准一个人,如果这个人被毙掉了,那么相当于进入了 \(n-1\) 个人的状态,否则等价于每个人都向前移动了一个位置,原来第 \(k\) 个位置上的人挪到了第 \(k-1\) 个位置上,故我们考虑设 \(dp_{i,j}\) 表示在有 \(i\) 个人的状态下,第 \(j\) 个人成为唯一的幸存者的概率。考虑转移,这里不妨假设 \(j>2\),考虑第一个人是否被毙掉,如果被毙掉了那么相当于 \(i-1\) 个人中第 \(j-1\) 个人成为唯一幸存者的概率,即 \(P_0dp_{i-1,j-1}\),否则每个人都向前挪了一位,原来第 \(j\) 个人变成了第 \(j-1\) 个人,即 \((1-P_0)dp_{i,j-1}\),故我们有 \(dp_{i,j}=P_0dp_{i-1,j-1}+(1-P_0)dp_{i,j-1}\),这样可以得到 \(i-1\) 个方程,可是要求出每个 \(dp_{i,j}\) 至少要 \(i\) 个方程啊……别急,显然最终幸存者一定存在于这 \(i\) 个人当中,因此所有 \(dp_{i,j}\) 的和为 \(1\),即 \(\sum\limits_{j=1}^idp_{i,j}=1\),这样就有 \(i\) 个方程了,可高斯消元了,复杂度 \(n·n^3=n^4\),一脸过不去的样子。

注意到这题中方程组的特殊性,如果我们先求出 \(dp_{1}\),在求出 \(dp_2,dp_3,\cdots\),那么在求 \(dp_{i,j}\) 时,\(P_0dp_{i-1,j-1}\) 必定是一个常数,也就是说前面 \(i-1\) 个方程都可以写成 \(dp_{i,j}=adp_{i,j-1}+b_j\) 的形式,因此我们考虑将所有 \(dp_{i,j}\) 都表示为 \(x_jdp_{i,1}+y_j\) 的形式,这显然可以在线性时间内求出,具体来说就 \(x_j=(1-P_0)x_{j-1},y_j=(1-P_0)y_{j-1}+P_0dp_{i-1,j-1}\),线性递推即可,这样最后 \(\sum\limits_{j=1}^idp_{i,j}=1\) 就可以化为 \((\sum\limits_{j=1}^ix_j)dp_{i,1}+(\sum\limits_{j=1}^iy_j)=1\),简单解个方程即可求出 \(dp_{i,1}\),然后再回代递推出其他 \(dp_{i,j}\) 即可,这样复杂度即可降到 \(n^2\)。

由于每次我们求 \(dp_i\) 只用到 \(dp_{i-1}\) 的值,因此需采用滚动数组优化空间,这样空间复杂度即可降到 \(\mathcal O(n)\)。

const int EPS=1e-8;
const int MAXN=1e4;
double p0;int n,k;
double pre[MAXN+5],cur[MAXN+5];
double calc(int n){
double sa=1,sb=0,cur=1,sum=0;
for(int i=2;i<=n;i++){
cur*=(1-p0);sum*=(1-p0);sa+=cur;
sum+=pre[i-1]*p0;sb+=sum;
} return (1-sb)/sa;
}
int main(){
scanf("%lf%d%d",&p0,&n,&k);
if(p0==0) return printf("%d\n",(n==1)?1:0),0;
pre[1]=1;
for(int i=2;i<=n;i++){
cur[1]=calc(i);
for(int j=2;j<=i;j++) cur[j]=cur[j-1]*(1-p0)+pre[j-1]*p0;
for(int j=1;j<=i;j++) pre[j]=cur[j];
} printf("%.10lf\n",pre[k]);
return 0;
}

最新文章

  1. Java之HashMap在多线程情况下导致死循环的问题
  2. Xiaomi 手机
  3. Teradata SQL tips
  4. Oracle truncate和delete的区别
  5. 洛谷P1613 跑路
  6. 未完待续的JAVA基础知识
  7. 135. Candy
  8. HDOJ(HDU) 1720 A+B Coming(进制)
  9. [Design Pattern] Command Pattern 简单案例
  10. USACO6.4-Wisconsin Squares:搜索
  11. Linux 终端訪问 FTP 及 上传下载 文件
  12. Week13(12月5日):不怕错误,慢慢来 :)
  13. java 字符串替换函数replaceAll 一次同时替换多个字符串
  14. Chapter 4 Invitations——10
  15. html小知识点(220-1)
  16. write RE validation
  17. RNA测序的质量控制
  18. 23个Python爬虫开源项目代码
  19. python 列表返回重复数据的下标
  20. 【Tomcat】Tomcat安装及Eclipse配置教程

热门文章

  1. springboot 事务执行全流程分析
  2. 第二次Alpha Scrum Meeting
  3. Alpha项目展示
  4. 热身训练1 Calculator
  5. hdu 5090 Game with Pearls (额,, 想法题吧 / 二分图最大匹配也可做)
  6. IDEA免费激活至2099年教程,亲测可用
  7. 【mysql3】我的大学teacher课程进行中|持续更新系列!
  8. 前端调试工具(DevTools)
  9. git删除未被追踪的文件
  10. The &#39;stream().forEach()&#39; chain can be replaced with &#39;forEach()&#39; (may change semantics)