题解 [CF838F] Expected Earnings
有一个巨大的坑
若令 \(i, j\) 为状态「取了 \(i\) 个球,有 \(j\) 个是红球」
则可能的 \(k\) 的范围显然是 \([j, n-(i-j)]\)
但每个 \(k\) 在这个范围内的概率比已经与原来不同了,即不是 \(\frac{p_k}{\sum\limits_{t=j}^n p_t}\)
原因的话晚上问下战神
好的问完了
这个题概率的比例会变是因为红球的总数是不确定的
而在不同的红球总数下在每个位置出现红球的概率也是不一样的
于是当我们确定了某个地方是红球时,总数的概率比也就发生变化了
举个例子:\(k=1, 2, 3\) 的概率都是 \(\frac{1}{3}\)
于是情况有
1 0 0
0 1 0
0 0 1
1 1 0
1 0 1
0 1 1
1 1 1
而若我们确定了第一个球不是红球,则由上表可知有1个和2个红球的概率比由 \(1:1\) 变为了 \(2:1\)
- 若 \(P(B|A)\) 较好求而 \(P(A|B)\) 不好求,也许可以用贝叶斯公式将 \(P(A|B)\) 转化成 \(\frac{P(A)P(B|A)}{P(B)}\) 求解
这题推导的草稿纸夹在一本书里了……懒得抄上来了
那个优化P的地方很神奇可以看一看
Code:
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 100010
#define ll long long
//#define int long long
char buf[1<<21], *p1=buf, *p2=buf;
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf, 1, 1<<21, stdin)), p1==p2?EOF:*p1++)
inline int read() {
int ans=0, f=1; char c=getchar();
while (!isdigit(c)) {if (c=='-') f=-f; c=getchar();}
while (isdigit(c)) {ans=(ans<<3)+(ans<<1)+(c^48); c=getchar();}
return ans*f;
}
int n;
double dp[2][N], q[2][N], x;
#define now (i&1)
signed main()
{
n=read(); x=read(); x/=1e6;
for (int i=0; i<=n; ++i) q[n%2][i]=read(), q[n%2][i]/=1e6;
for (int i=n-1; ~i; --i) {
for (int j=0; j<=i; ++j) {
q[now][j]=1.0*(j+1)/(i+1)*q[now^1][j+1]+1.0*(i+1-j)/(i+1)*q[now^1][j];
if (q[now][j]<1e-18) continue;
double p=q[now^1][j+1]*(j+1)/q[now][j]/(i+1);
dp[now][j]=max(0.0, (1-p)*dp[now^1][j]+p*(dp[now^1][j+1]+1)-x);
}
}
printf("%.10lf\n", dp[0][0]);
return 0;
}