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

    题目描述

    小 K 不慎被 LL 邪教洗脑了,洗脑程度深到他甚至想要从亚瑟王邪教中脱坑。他决定,在脱坑之前,最后再来打一盘亚瑟王。既然是最后一战,就一定要打得漂亮。众所周知,亚瑟王是一个看脸的游戏,技能的发动都是看概率的。

    作为一个非洲人,同时作为一个前 OIer,小 K 自然是希望最大化造成伤害的期望值。但他已经多年没写过代码,连 Spaly都敲不对了,因此,希望你能帮帮小 K,让他感受一下当欧洲人是怎样的体验。

    本题中我们将考虑游戏的一个简化版模型。 玩家有一套卡牌,共 n张。游戏时,玩家将 n 张卡牌排列成某种顺序,排列后将卡牌按从前往后依次编号为 1 ~ n。本题中,顺序已经确定,即为输入的顺序。每张卡牌都有一个技能。第 i 张卡牌的技能发动概率为 pi,如果成功发动,则会对敌方造成di点伤害。也只有通过发动技能,卡牌才能对敌方造成伤害。基于现实因素以及小K非洲血统的考虑,pi不会为 0,也不会为 1,即 0 < pi < 1。 一局游戏一共有 r 轮。在每一轮中,系统将从第一张卡牌开始,按照顺序依次考虑每张卡牌。在一轮中,对于依次考虑的每一张卡牌:

    1如果这张卡牌在这一局游戏中已经发动过技能,则

    1.1 如果这张卡牌不是最后一张,则跳过之(考虑下一张卡牌); 否则(是最后一张),结束这一轮游戏。

    2否则(这张卡牌在这一局游戏中没有发动过技能),设这张卡牌为第 i 张

    2.1将其以 pi的概率发动技能。

    2.2如果技能发动,则对敌方造成 di点伤害,并结束这一轮。

    2.3如果这张卡牌已经是最后一张(即 i 等于n),则结束这一轮;否则,考虑下一张卡牌。

    请帮助小 K 求出这一套卡牌在一局游戏中能造成的伤害的期望值。

    输入输出格式

    输入格式:

    输入文件的第一行包含一个整数 T,代表测试数据组数。 接下来一共 T 组数据。 每组数据的第一行包含两个用空格分开的整数 n和r,分别代表卡牌的张数和游戏的轮数。 接下来 n行,每行包含一个实数和一个整数,由空格隔开,描述一张卡牌。第i 行的两个数为 pi和 di,分别代表第 i 张卡牌技能发动的概率(实数)和技能发动造成的伤害(整数)。保证 pi最多包含 4位小数,且为一个合法的概率。

    输出格式:

    对于每组数据,输出一行,包含一个实数,为这套卡牌在这一局游戏中造成的伤害的期望值。对于每一行输出,只有当你的输出和标准答案的相对误差不超过10^-8时——即|a-o|/a<=10-8时(其中a是标准答案,o是输出),你的输出才会被判为正确。建议输出10 位小数。

    输入输出样例

    输入样例#1: 
    1
    3 2
    0.5000 2
    0.3000 3
    0.9000 1
    输出样例#1: 
    3.2660250000

    说明

    一共有 13 种可能的情况:

    1. 第一轮中,第 1张卡牌发动技能;第二轮中,第 2张卡牌发动技能;

    概率为 0.15,伤害为5。

    1. 第一轮中,第 1张卡牌发动技能;第二轮中,第 3张卡牌发动技能;

    概率为 0.315,伤害为3。

    1. 第一轮中,第 1张卡牌发动技能;第二轮不发动技能;

    概率为 0.035,伤害为2。

    1. 第一轮中,第 2张卡牌发动技能;第二轮中,第 1张卡牌发动技能;

    概率为 0.075,伤害为5。

    1. 第一轮中,第 2张卡牌发动技能;第二轮中,第 3张卡牌发动技能;

    概率为 0.0675,伤害为4。

    1. 第一轮中,第 2张卡牌发动技能;第二轮不发动技能;

    概率为 0.0075,伤害为3。

    1. 第一轮中,第 3张卡牌发动技能;第二轮中,第 1张卡牌发动技能;

    概率为 0.1575,伤害为3。

    1. 第一轮中,第 3张卡牌发动技能;第二轮中,第 2张卡牌发动技能;

    概率为 0.04725,伤害为4。

    1. 第一轮中,第 3张卡牌发动技能;第二轮不发动技能;

    概率为 0.11025,伤害为1。

    1. 第一轮不发动技能;第二轮中,第 1张卡牌发动技能;

    概率为 0.0175,伤害为2。

    1. 第一轮不发动技能;第二轮中,第 2张卡牌发动技能;

    概率为 0.00525,伤害为3。

    1. 第一轮不发动技能;第二轮中,第 3张卡牌发动技能;

    概率为 0.011025,伤害为1。

    1. 第一轮不发动技能;第二轮亦不发动技能;

    概率为 0.001225,伤害为0。

    造成伤害的期望值为概率与对应伤害乘积之和,为 3.266025。

    对于所有测试数据, 1 <= T <= 444, 1 <= n <= 220, 0 <= r <= 132, 0 < pi < 1, 0 <= di <= 1000。

    除非备注中有特殊说明,数据中 pi与di均为随机生成。

    请注意可能存在的实数精度问题,并采取适当措施。

    突破点就是在编号小的优先级总是更大的,所以我们可以第一维枚举考虑了前几小的编号,第二维枚举还剩多少局没有匹配卡牌。

    #include<bits/stdc++.h>
    #define ll long long
    #define D double
    using namespace std;
    D f[225][141],ans;
    D p[225],R,P[225][141];
    int T,n,r,d[225];
    // f[i][j] 表示到了考虑 i 的时候,
    //还有j局没有输出的概率。 
    //P[i][j] 表示i在j局后还没有被选的概率 
    
    inline void dp(){
    	for(int i=1;i<=n;i++){
    		P[i][0]=1;
    		for(int j=1;j<=r;j++) P[i][j]=P[i][j-1]*(1-p[i]);
    	}
    	
    	f[1][r]=1,ans+=d[1]*(1-P[1][r]);
    	for(int i=2;i<=n;i++){
    		R=0;
    		for(int j=max(0,r-i+1);j<=r;j++){
    			f[i][j]=f[i-1][j]*P[i-1][j];
    			if(j<r) f[i][j]+=f[i-1][j+1]*(1-P[i-1][j+1]);
    			R+=f[i][j]*(1-P[i][j]);
    		}
    		ans+=R*d[i];
    	}
    }
    
    int main(){
    	scanf("%d",&T);
    	while(T--){
    		ans=0,scanf("%d%d",&n,&r);
    		for(int i=1;i<=n;i++) scanf("%lf%d",p+i,d+i);
    		memset(f,0,sizeof(f)),memset(P,0,sizeof(P)),dp();
    		printf("%.10lf
    ",ans);
    	}
    	
    	return 0;
    }
    

      

     

  • 相关阅读:
    Allegro PCB Design GXL (legacy) 使用slide无法将走线推挤到焊盘的原因
    OrCAD Capture CIS 16.6 导出BOM
    Altium Designer (17.0) 打印输出指定的层
    Allegro PCB Design GXL (legacy) 将指定的层导出为DXF
    Allegro PCB Design GXL (legacy) 设置十字大光标
    Allegro PCB Design GXL (legacy) 手动更改元器件引脚的网络
    magento产品导入时需要注意的事项
    magento url rewrite
    验证台湾同胞身份证信息
    IE8对css文件的限制
  • 原文地址:https://www.cnblogs.com/JYYHH/p/8549862.html
Copyright © 2011-2022 走看看