zoukankan      html  css  js  c++  java
  • bzoj 4008 [HNOI2015] 亚瑟王

    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] imes (1-p[i+1])^j)

    如果第(i+1)张卡牌被用到了,那么少了一次机会,多了一些伤害

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

    然后答案会加(f[i][j] imes(1-(1-p[i+1])^j) imes 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
    ",ans);
    	}
    	return 0;
    }
    
  • 相关阅读:
    算法
    用python代码编写象棋界面,棋盘覆盖问题
    深浅拷贝的原理
    MongoDB简介,安装,增删改查
    DBUtils-Python数据库连接池
    websocket
    Python操作 RabbitMQ、Redis、Memcache、SQLAlchemy
    跨域
    最长公共子序列/子串 LCS(模板)
    寒假作业---蓝桥杯---DFS
  • 原文地址:https://www.cnblogs.com/wawawa8/p/9557552.html
Copyright © 2011-2022 走看看