1. 程式人生 > >bzoj 4008 [HNOI2015] 亞瑟王

bzoj 4008 [HNOI2015] 亞瑟王

first problem getchar += har long long inline ace pro

bzoj 4008 [HNOI2015] 亞瑟王

題面

[題面][https://www.lydsy.com/JudgeOnline/problem.php?id=4008]

題解

我們令\(f[i][j]\)表示當前考慮了前\(i\)張卡牌,前\(i\)張牌一共剩下\(j\)次機會的概率是多少

那麽\(f[0][r]=1\)

然後遞推地求解

如果第\(i+1\)張卡牌沒有用到 那麽\(f[i+1][j]+=f[i][j]\times (1-p[i+1])^j\)

如果第\(i+1\)張卡牌被用到了,那麽少了一次機會,多了一些傷害

\(f[i+1][j-1]+=f[i][j]\times (1-(1-p[i+1])^j)\)

然後答案會加\(f[i][j]\times(1-(1-p[i+1])^j)\times d[i+1]\)

就是概率乘傷害

Review

這題據TRCYX說是NewTrain最難得期望dp

我覺得主要是狀態難想,因為考慮到某一張牌只和前面的牌有關,和後面的牌無關,而且出牌的順序也不影響答案,於是把\(r\)輪搞成\(r\)次機會,所以想到這個狀態

Code

#include<stdio.h>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<iostream>
#include<queue>
#include<string>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<long long,long long> pll;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define rep(i,j,k)  for(register int i=(int)(j);i<=(int)(k);i++)
#define rrep(i,j,k) for(register int i=(int)(j);i>=(int)(k);i--)

ll read(){
    ll x=0,f=1;char c=getchar();
    while(c<‘0‘ || c>‘9‘){if(c==‘-‘)f=-1;c=getchar();}
    while(c>=‘0‘ && c<=‘9‘){x=x*10+c-‘0‘;c=getchar();}
    return x*f;
}

int T;
int n,r,d[255];
double p[255];
double f[255][255],pw[255][255];

int main()
{
    T=read();
    while(T--)
    {
        n=read();r=read();
        memset(f,0,sizeof(f));
        for(int i=1;i<=n;i++)
        {
            scanf("%lf",&p[i]);
            d[i]=read();
        }
        double ans=0;
        for(int i=1;i<=n;i++)
        {
            pw[i][0]=1;
            for(int j=1;j<=r;j++)pw[i][j]=pw[i][j-1]*(1-p[i]);
        }
        f[0][r]=1;
        for(int i=0;i<n;i++)
            for(int j=0;j<=r;j++)
            {
                f[i+1][j]+=f[i][j]*pw[i+1][j];
                if(j-1>=0)
                {
                    f[i+1][j-1]+=f[i][j]*(1-pw[i+1][j]);
                    ans+=f[i][j]*(1-pw[i+1][j])*d[i+1];
                }
            }
        printf("%.10lf\n",ans);
    }
    return 0;
}

bzoj 4008 [HNOI2015] 亞瑟王