zoukankan      html  css  js  c++  java
  • [loj6118]鬼牌

    枚举最终所有牌的大小$i$,对于最终所有牌大小都为$i$的情况,令其贡献为步数,否则令其贡献为0,记$F$为期望贡献(即所有情况概率*贡献之和),答案即为$sum_{i=1}^{m}F$

    显然,$F$仅取决于牌的数量,定义$F_{i}$表示恰有$i$张牌的期望贡献,那么答案即为$sum_{i=1}^{m}F_{a_{i}}$

    在求$F_{i}$的转移之前,先定义$P_{i}$为贡献为步数的情况的概率,关于$P_{i}$的转移,不难得到
    $$
    egin{cases}P_{0}=0,P_{n}=1\P_{i}=frac{P_{i-1}+P_{i+1}}{2}&(1le i<n)end{cases}
    $$
    这是一个经典的问题,通项为$P_{i}=frac{i}{n}$

    考虑$F_{i}$的转移,即为
    $$
    egin{cases}F_{0}=F_{n}=0\F_{i}=frac{i(n-i)}{n(n-1)}(F_{i-1}+F_{i+1}+frac{2i}{n})+(1-frac{2i(n-i)}{n(n-1)})(F_{i}+frac{i}{n})&(1le i<n)end{cases}
    $$
    (注意每一次步数并不是+1,而是加上目标状态的$P_{i}$,因为只有$P_{i}$的概率这步有贡献)

    将其化简,即为
    $$
    egin{cases}F_{0}=F_{n}=0\F_{i+1}=2F_{i}-F_{i-1}-frac{n-1}{n-i}&(1le i<n)end{cases}
    $$
    将其差分,即令$G_{i}=F_{i+1}-F_{i}$,那么
    $$
    egin{cases}G_{0}=F_{1},sum_{i=0}^{n-1}G_{i}=0\G_{i}=G_{i-1}-frac{n-1}{n-i}&(1le i<n)end{cases}
    $$
    将第2个式子不断迭代,即可得$G_{i}=F_{1}-sum_{j=1}^{i}frac{n-1}{n-j}$,那么
    $$
    sum_{i=0}^{n-1}G_{i}=nF_{1}-sum_{i=0}^{n-1}sum_{j=1}^{i}frac{n-1}{n-j}=nF_{1}-sum_{j=1}^{n-1}frac{n-1}{n-j}(n-j)=nF_{1}-(n-1)^{2}=0
    $$
    解得$F_{1}=frac{(n-1)^{2}}{n}$,进而可得
    $$
    F_{i}=sum_{j=0}^{i-1}G_{j}=iF_{1}-sum_{j=1}^{i-1}frac{n-1}{n-j}(i-j)=frac{i(n-1)^{2}}{n}-(i-1)(n-1)+(n-i)(n-1)sum_{j=n-i+1}^{n-1}frac{1}{j}
    $$
    (最后一个变化是将$i-j$变形为$(n-j)-(n-i)$,再根据分配律展开即可)

    关于最后一项,令$H_{n}=sum_{i=1}^{n}frac{1}{i}$,即$H_{n}-H_{n-i}$,关于$H_{n}$为调和级数,用$H_{n}=ln n+C$来模拟即可(较小范围预处理,$C$使用0.5772即可,当然还可以分块打表)

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 #define N 10000005
     4 #define C 0.5772
     5 #define ld long double
     6 int n,m,x;
     7 ld nn,ans,h[N];
     8 ld H(int n){
     9     if (n<N)return h[n];
    10     return log(n)+C;
    11 }
    12 ld calc(int k){
    13     return k*(nn-1)*(nn-1)/nn-(k-1)*(nn-1)+(nn-k)*(nn-1)*(H(n-1)-H(n-k));
    14 }
    15 int main(){
    16     for(int i=1;i<N;i++)h[i]=h[i-1]+(ld)1/i;
    17     scanf("%d%d",&n,&m);
    18     nn=n;
    19     for(int i=1;i<=m;i++){
    20         scanf("%d",&x);
    21         ans+=calc(x);
    22     }
    23     printf("%.7Lf",ans);
    24 }
    View Code
  • 相关阅读:
    团队项目-第一阶段冲刺7
    团队项目-第一阶段冲刺6
    Spring Boot 揭秘与实战(七) 实用技术篇
    Spring Boot 揭秘与实战(七) 实用技术篇
    Spring Boot 揭秘与实战(六) 消息队列篇
    Spring Boot 揭秘与实战(五) 服务器篇
    Spring Boot 揭秘与实战(五) 服务器篇
    Spring Boot 揭秘与实战(五) 服务器篇
    Spring Boot 揭秘与实战(五) 服务器篇
    Spring Boot 揭秘与实战(四) 配置文件篇
  • 原文地址:https://www.cnblogs.com/PYWBKTDA/p/15010970.html
Copyright © 2011-2022 走看看