A Dangerous Maze (II)(妙用期望定义-dp)
发布日期:2021-06-30 10:23:22 浏览次数:2 分类:技术文章

本文共 1552 字,大约阅读时间需要 5 分钟。

首先因为这个能记住前 k k k条路很不好搞

因为 d p dp dp过程中无法知道它记住的是那些门

所以就需要把门抽象成两类

一种是进去后回到起点,花费总时间 v a l 1 val_1 val1,有 s 1 s_1 s1扇门

一种是进去后就能逃生,花费总时间 v a l 2 val_2 val2,有 s 2 s_2 s2扇门

这样把所有第一类门权值看作 v a l 1 s 1 \frac{val_1}{s_1} s1val1,把所有第二类门看作 v a l 2 s 2 \frac{val_2}{s_2} s2val2

因为对于同一类门来说,被选到的概率均等,造成的影响相同,所以可以用期望代替

这样我们就可以不去关心目前记住的是那些门,只需要知道记住了多少门就行!!

f [ i ] f[i] f[i]为记住了 i i i扇门,逃生还需花费的时间

先对 k k k处理一下, k = m i n ( k , s 1 ) k=min(k,s_1) k=min(k,s1)

那么终止点就是 f [ k ] = ( f [ k ] + v a l 1 ) ∗ p 1 + v a l 2 ∗ p 2 f[k]=(f[k]+val_1)*p_1+val_2*p_2 f[k]=(f[k]+val1)p1+val2p2

其中 p 1 = s 1 − k n − k p_1=\frac{s_1-k}{n-k} p1=nks1k表示此时去第一类门

其中 p 2 = s 2 n − k p_2=\frac{s_2}{n-k} p2=nks2,表示去第二类门

然后一般情况递推式是 f [ i ] = ( f [ i + 1 ] + v a l 1 ) ∗ s 1 − i n − i + v a l 2 ∗ s 2 n − i f[i]=(f[i+1]+val_1)*\frac{s_1-i}{n-i}+val_2*\frac{s_2}{n-i} f[i]=(f[i+1]+val1)nis1i+val2nis2

f [ 0 ] f[0] f[0]就是答案

#include 
using namespace std;int n,k;double f[109];int main(){
int t,casenum=0; cin >> t; while( t-- ) {
cin >> n >> k; double val1=0,val2=0,s1=0,s2=0; for(int i=1;i<=n;i++) {
double x; cin >> x; if( x<0 ) val1 -= x,s1++; else val2 += x,s2++; } if( s2==0 ) {
printf("Case %d: -1\n",++casenum); continue; } if( s1>0.0 )val1 /= s1; if( s2>0.0 )val2 /= s2; k = min( k,(int)s1 ); double p1 = (s1-k)/(n-k), p2 = s2/(n-k); f[k] = val1*p1+val2*p2; f[k] /= (1.0-p1); for(int i=k-1;i>=0;i--) {
p1 = (s1-i)/(n-i), p2 = s2/(n-i); f[i] = ( f[i+1]+val1 )*p1+val2*p2; } printf("Case %d: %.7lf\n",++casenum,f[0] ); }}

转载地址:https://issue-is-vegetable.blog.csdn.net/article/details/109350787 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:POJ3621 最优比率环[模板]
下一篇:Expected Cards(记忆化搜索dp)

发表评论

最新留言

感谢大佬
[***.8.128.20]2024年04月29日 17时09分11秒