LightOJ 1395 A Dangerous Maze (II) 期望DP

A Dangerous Maze (II) LightOJ - 1395

这个题是 LightOJ 1027 A Dangerous Maze 基础概率DP 的加强版。

n n n 个门,其中有些门通过之后, x i x_i xi 分钟后会回到原点,另一些门通过后, x i x_i xi 分钟后会出去,现在能够记住最近的 K K K 次选择,下次选择时会从剩下的未在这 K K K 次选择中出现的门进行选择,问出去的期望时间。

首先这 K K K 次记住的肯定是未出去的门,因为假如出去的话就已经结束了,不需要再进行选择,定义出去的门为集合 A \mathcal{A} A,返回的门为集合 B \mathcal{B} B,用 d p [ i ] dp[i] dp[i] 表示记忆了 i i i 个未出去的门对应的期望,分两种情况进行讨论:

(1)假如 K ≥ ∣ B ∣ K\ge|\mathcal{B}| KB,也就是说记忆的 K K K 个经验能够包括到所有回来的门,则 d p [ ∣ B ∣ ] = 1 ∣ A ∣ ∑ i ∈ A x i dp[|\mathcal{B}|]=\dfrac{1}{|\mathcal{A}|}\sum\limits_{i\in\mathcal{A}}x_i dp[B]=A1iAxi,即此时的期望就等于从能够出去的门中选一个之后的期望时间。此时再推 j < ∣ B ∣ j<|\mathcal{B}| j<B 时对应的 d p dp dp 值,此时 d p [ j ] = 1 n − j ∑ i ∈ A x i + 1 n − j ( ∑ i ∈ B ∖ C ( x i + d p [ j + 1 ] ) ) dp[j]=\dfrac{1}{n-j}\sum\limits_{i\in\mathcal{A}}x_i+\dfrac{1}{n-j}(\sum\limits_{i\in\mathcal{B}\setminus\mathcal{C}}(x_i+dp[j+1])) dp[j]=nj1iAxi+nj1(iBC(xi+dp[j+1])),其中 C \mathcal{C} C 表示已经选择过的 j j j 个不能出去的门的集合, B ∖ C \mathcal{B}\setminus\mathcal{C} BC 表示还未选择的不能出去的门的集合,因为 C \mathcal{C} C 是一个随机选择出来的集合,可以证明:

∑ i ∈ B ∖ C x i = ∣ B ∖ C ∣ ∣ B ∣ ∑ i ∈ B x i \sum_{i\in\mathcal{B}\setminus\mathcal{C}}x_i=\frac{|\mathcal{B}\setminus\mathcal{C}|}{|\mathcal{B}|}\sum_{i\in\mathcal{B}}x_i iBCxi=BBCiBxi

因此:

d p [ j ] = 1 n − j ∑ i ∈ A x i + ∣ B ∖ C ∣ n − j ( ∑ i ∈ B x i ∣ B ∣ + d p [ j + 1 ] ) d p [ j ] = 1 n − j ∑ i ∈ A x i + ∣ B ∣ − j n − j ( ∑ i ∈ B x i ∣ B ∣ + d p [ j + 1 ] ) \begin{aligned} dp[j]&=\frac{1}{n-j}\sum_{i\in\mathcal{A}}x_i+\frac{|\mathcal{B}\setminus\mathcal{C}|}{n-j}(\frac{\sum_{i\in\mathcal{B}}x_i}{|\mathcal{B}|}+dp[j+1])\\ dp[j]&=\frac{1}{n-j}\sum_{i\in\mathcal{A}}x_i+\frac{|\mathcal{B}|-j}{n-j}(\frac{\sum_{i\in\mathcal{B}}x_i}{|\mathcal{B}|}+dp[j+1])\\ \end{aligned} dp[j]dp[j]=nj1iAxi+njBC(BiBxi+dp[j+1])=nj1iAxi+njBj(BiBxi+dp[j+1])
逆推即可以求得 d p [ 0 ] dp[0] dp[0]

(2)假如 K < ∣ B ∣ K<|\mathcal{B}| K<B,也就是说并不能完全记住所有的返回门,那么 j = K j=K j=K 时:

d p [ K ] = 1 n − K ∑ i ∈ A x i + ∣ B ∣ − K n − K ( ∑ i ∈ B x i ∣ B ∣ + d p [ K ] ) d p [ K ] = 1 n − ∣ B ∣ ∑ i ∈ A x i + ∣ B ∣ − K n − ∣ B ∣ ∑ i ∈ B x i ∣ B ∣ \begin{aligned} dp[K]&=\frac{1}{n-K}\sum_{i\in\mathcal{A}}x_i+\frac{|\mathcal{B}|-K}{n-K}(\frac{\sum_{i\in\mathcal{B}}x_i}{|\mathcal{B}|}+dp[K])\\ dp[K]&=\frac{1}{n-|\mathcal{B}|}\sum_{i\in\mathcal{A}}x_i+\frac{|\mathcal{B}|-K}{n-|\mathcal{B}|}\frac{\sum_{i\in\mathcal{B}}x_i}{|\mathcal{B}|}\\ \end{aligned} dp[K]dp[K]=nK1iAxi+nKBK(BiBxi+dp[K])=nB1iAxi+nBBKBiBxi

j < K j<K j<K 时:

d p [ j ] = 1 n − j ∑ i ∈ A x i + ∣ B ∣ − j n − j ( ∑ i ∈ B x i ∣ B ∣ + d p [ j + 1 ] ) dp[j]=\frac{1}{n-j}\sum_{i\in\mathcal{A}}x_i+\frac{|\mathcal{B}|-j}{n-j}(\frac{\sum_{i\in\mathcal{B}}x_i}{|\mathcal{B}|}+dp[j+1]) dp[j]=nj1iAxi+njBj(BiBxi+dp[j+1])

也可以逆推求得 d p [ 0 ] dp[0] dp[0]

代码如下:

#include<iostream>
#include<cstdio>
#include<algorithm>
//#define WINE
using namespace std;
int T,iCase,n,K,a,ca,cb,sa,sb;
double res;
int main(){
#ifdef WINE
    freopen("data.in","r",stdin);
#endif
    scanf("%d",&T);
    while(T--){
        scanf("%d%d",&n,&K);
        ca=cb=sa=sb=0;
        for(int i=0;i<n;i++){
            scanf("%d",&a);
            if(a>0)ca++,sa+=a;
            else cb++,sb+=-a;
        }
        if(cb==n){
            printf("Case %d: -1\n",++iCase);
            continue;
        }
        K=min(K,cb);
        if(K<cb)res=1.0/(n-cb)*sa+1.0*(cb-K)*sb/(n-cb)/cb;
        else res=1.0*sa/ca;
        for(int j=K-1;j>=0;j--)
            res=1.0*sa/(n-j)+1.0*(cb-j)/(n-j)*(1.0*sb/cb+res);
        printf("Case %d: %.8lf\n",++iCase,res);
    }
    return 0;
}

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值