1. 程式人生 > >【BZOJ4008】【HNOI2015】亞瑟王 概率DP

【BZOJ4008】【HNOI2015】亞瑟王 概率DP

name spa 題解 rect printf noi size mem turn

鏈接:

#include <stdio.h>
int main()
{
    puts("轉載請註明出處[輾轉山河弋流歌 by 空灰冰魂]謝謝");
    puts("網址:blog.csdn.net/vmurder/article/details/46461649");
}

題解:

f(i,j) 表示分配給第 [i,n] 張牌 j 次機會的期望。
然後 f(i,j)=f(i?1,j)?(1?pi?1)j)+f(i?1,j+1)?(1?(1?pi?1)j+1)

總結:

有的時候反過來想,比方求選的概率。記錄不選的概率可能會更好一些。


再比方這道題。不從前面遞推,而考慮 f(i) 表示 [i,n]。

代碼:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;

int n,m;
long double ans;
long double p[233],d[233],f[233][333];

long double power(long
double x,int p) { long double ret=1.0; while(p) { if(p&1)ret*=x; x*=x,p>>=1; } return ret; } int main() { freopen("test.in","r",stdin); int i,j,T; double a,b; for(scanf("%d",&T);T--;) { memset(f,0,sizeof f); scanf("%d%d"
,&n,&m); for(i=1;i<=n;i++) { scanf("%lf%lf",&a,&b); p[i]=a,d[i]=b; } f[0][m]=1.0,ans=0.0; for(i=1;i<=n;i++)for(j=1;j<=m;j++) { f[i][j]=f[i-1][j]*power(1-p[i-1],j)+f[i-1][j+1]*(1-power(1-p[i-1],j+1)); ans+=f[i][j]*(1-power(1-p[i],j))*d[i]; } printf("%.10lf\n",(double)ans); } return 0; }

【BZOJ4008】【HNOI2015】亞瑟王 概率DP