[Lydsy2017年4月月赛]抵制克苏恩题解

  考试的时候以为就是简单的概率期望题,考完后知道是简单的概率期望DP题,完美爆零。

  这道题数据范围很小,很容易让人想到状压,不过貌似没什么可压的。那么只能说明这道题复杂度很高了,状态数组f[o][i][j][k]为第o次攻击后出现有i个1滴血的j个2滴血的,k个3滴血的情况的概率。那么转移方程就明了了。

  1.f[o][i][j][k]+=f[o-1][i][j][k]/(i+j+k+1)英雄收到攻击

  2.f[o][i][j][k]+=f[o-1][i+1][j][k]*(i+1)/(i+j+k+2)有一个1滴血的奴隶主被击杀。前提是i+j+k+1<=7

  3.f[o][i][j][k]+=f[o-1][i-1][j+1][k-1]*(j+1)/(i+j+k)有一个2滴血的奴隶主收到攻击,召唤一个奴隶主,前提是i!=0&&k!=0

  4.f[[o][i][j][k]+=f[o-1][i][j-1][k]*(k/i+j+k)有一个3滴血的奴隶主收到攻击,召唤一个奴隶主,前提是j!=0。

  5由于仆从满7个后不会再召唤,所以当i+j+k=7时需要特判受到攻击却未召唤的情况,即f[o][i][j][k]+=f[o-1][i-1][j+1][k],f[o][i][j][k]+=f[o-1][i][j-1][k+1],前提分别为i!=0,j!=0。

  转移方程写出来别挂精度上就行了,但是要注意我们的状态为受到攻击后场上局面的状态,真正结果为0~k-1中所有状态转移方程中1/仆从+1,一开始写的为1~k身败名裂……

 1 #include<iostream>
 2 #include<cstdlib>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<queue>
 6 #include<algorithm>
 7 #include<cmath>
 8 using namespace std;
 9 int t,n;
10 double f[55][10][10][10];
11 int main(){
12 //  freopen("defcthun.in","r",stdin);
13 //  freopen("defcthun.out","w",stdout);
14     scanf("%d",&t);
15 while(t--)
16 {
17     memset(f,0,sizeof(f));
18     scanf("%d",&n);
19     int xx,yy,zz;
20     scanf("%d%d%d",&xx,&yy,&zz);
21     f[0][xx][yy][zz]=1.0;
22     for(int o=1;o<n;o++)
23     {
24         for(int i=0;i<=7;i++)
25         {
26             for(int j=0;j<=7;j++)
27             {
28                 for(int k=0;k<=7;k++)
29                 {
30                     if(i+j+k>7)break;
31                     if(i+j+k+1<=7) f[o][i][j][k]+=f[o-1][i+1][j][k]*(double(i+1)/double(i+1+j+k+1));
32                     f[o][i][j][k]+=f[o-1][i][j][k]/double(i+j+k+1);
33                     if(i&&k) f[o][i][j][k]+=f[o-1][i-1][j+1][k-1]*(double(j+1)/double(i+k+j));
34                     if(j) f[o][i][j][k]+=f[o-1][i][j-1][k]*(double(k)/double(i+j+k));
35                     if(i+j+k==7)
36                     {
37                         if(i) f[o][i][j][k]+=f[o-1][i-1][j+1][k]*double(j+1)/double(i+j+k+1);
38                         if(j) f[o][i][j][k]+=f[o-1][i][j-1][k+1]*double(k+1)/double(i+j+k+1);
39                     }
40                 }
41             }
42         }
43     }
44     double sum=0.0;
45     for(int o=0;o<n;o++)
46     {
47         for(int i=0;i<=7;i++)
48         {
49             for(int j=0;j<=7;j++)
50             {
51                 for(int k=0;k<=7;k++)
52                 {
53                     if(i+j+k>7)break; sum+=f[o][i][j][k]*1.0/double(j+k+i+1);
54                 }
55             }
56         }
57     }
58     printf("%.2lf\n",sum);
59 }
60     //while(1);
61     return 0;
62 }
时间: 2024-10-15 07:14:31

[Lydsy2017年4月月赛]抵制克苏恩题解的相关文章

[Lydsy2017年4月月赛]抵制克苏恩

[Lydsy2017年4月月赛]抵制克苏恩 时间限制: 1 Sec  内存限制: 128 MB提交: 49  解决: 34[提交][状态][讨论版] 题目描述 小Q同学现在沉迷炉石传说不能自拔.他发现一张名为克苏恩的牌很不公平.如果你不玩炉石传说,不必担心,小Q同学会告诉你所有相关的细节.炉石传说是这样的一个游戏,每个玩家拥有一个 30 点血量的英雄,并且可以用牌召唤至多 7 个随从帮助玩家攻击对手,其中每个随从也拥有自己的血量和攻击力.小Q同学有很多次游戏失败都是因为对手使用了克苏恩这张牌,所

【BZOJ 4832 】 4832: [Lydsy2017年4月月赛]抵制克苏恩 (期望DP)

4832: [Lydsy2017年4月月赛]抵制克苏恩 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 275  Solved: 87 Description 小Q同学现在沉迷炉石传说不能自拔.他发现一张名为克苏恩的牌很不公平.如果你不玩炉石传说,不必担心,小Q 同学会告诉你所有相关的细节.炉石传说是这样的一个游戏,每个玩家拥有一个 30 点血量的英雄,并且可以用牌 召唤至多 7 个随从帮助玩家攻击对手,其中每个随从也拥有自己的血量和攻击力.小Q同学

4832: [Lydsy2017年4月月赛]抵制克苏恩]【解题报告】

戳我 4832: [Lydsy2017年4月月赛]抵制克苏恩 时间限制: 1 Sec  内存限制: 128 MB提交: 752  解决: 289[提交][][] 题目描述 小Q同学现在沉迷炉石传说不能自拔.他发现一张名为克苏恩的牌很不公平.如果你不玩炉石传说,不必担心,小Q 同学会告诉你所有相关的细节.炉石传说是这样的一个游戏,每个玩家拥有一个 30 点血量的英雄,并且可以用牌 召唤至多 7 个随从帮助玩家攻击对手,其中每个随从也拥有自己的血量和攻击力.小Q同学有很多次游戏失败都是 因为对手使用

BZOJ4832: [Lydsy2017年4月月赛]抵制克苏恩

传送门 题目大意: 攻击k次,每次可攻击随从或英雄. 随从数不大于7个,且1滴血的a个,2滴b个,3滴c个. 攻击一次血-1,如果随从没死可以生成3滴血随从一个 题解: 概率/期望dp f[i][j][p][q]表示攻击i次,一滴血的有j个,二滴血的有p个,三滴血的有q个. 转移就是枚举打在谁身上 代码: #include<iostream> #include<cstdio> #include<cstring> using namespace std; int t,a,

【BZOJ 4832】 [Lydsy2017年4月月赛] 抵制克苏恩 期望概率dp

打记录的题打多了,忘了用开维记录信息了......我们用f[i][j][l][k]表示已经完成了i次攻击,随从3血剩j个,2血剩l个,1血剩k个,这样我们求出每个状态的概率,从而求出他们对答案的贡献并加和,一开始我用的期望忘了转移的时候不能用1而要用概率...... #include <cstdio> #include <cstring> #define r register using namespace std; typedef long double LD; inline i

[BZOJ 4832][lydsy 4月赛] 抵制克苏恩

题面贴一发 [Lydsy2017年4月月赛]抵制克苏恩 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 443  Solved: 164[Submit][Status][Discuss] Description 小Q同学现在沉迷炉石传说不能自拔.他发现一张名为克苏恩的牌很不公平.如果你不玩炉石传说,不必担心,小Q 同学会告诉你所有相关的细节.炉石传说是这样的一个游戏,每个玩家拥有一个 30 点血量的英雄,并且可以用牌 召唤至多 7 个随从帮助玩家攻击

bzoj 4836: [Lydsy2017年4月月赛]二元运算 -- 分治+FFT

4836: [Lydsy2017年4月月赛]二元运算 Time Limit: 8 Sec  Memory Limit: 128 MB Description 定义二元运算 opt 满足 现在给定一个长为 n 的数列 a 和一个长为 m 的数列 b ,接下来有 q 次询问.每次询问给定一个数字 c 你需要求出有多少对 (i, j) 使得 a_i  opt b_j=c . Input 第一行是一个整数 T (1≤T≤10) ,表示测试数据的组数. 对于每组测试数据: 第一行是三个整数 n,m,q (

【BZOJ4883】[Lydsy2017年5月月赛]棋盘上的守卫 KM算法

[BZOJ4883][Lydsy2017年5月月赛]棋盘上的守卫 Description 在一个n*m的棋盘上要放置若干个守卫.对于n行来说,每行必须恰好放置一个横向守卫:同理对于m列来说,每列 必须恰好放置一个纵向守卫.每个位置放置守卫的代价是不一样的,且每个位置最多只能放置一个守卫,一个守卫 不能同时兼顾行列的防御.请计算控制整个棋盘的最小代价. Input 第一行包含两个正整数n,m(2<=n,m<=100000,n*m<=100000),分别表示棋盘的行数与列数. 接下来n行,每

抵制克苏恩[Lydsy2017年4月月赛]

题目描述 小Q同学现在沉迷炉石传说不能自拔.他发现一张名为克苏恩的牌很不公平.如果你不玩炉石传说,不必担心,小Q同学会告诉你所有相关的细节.炉石传说是这样的一个游戏,每个玩家拥有一个 30 点血量的英雄,并且可以用牌召唤至多 7 个随从帮助玩家攻击对手,其中每个随从也拥有自己的血量和攻击力.小Q同学有很多次游戏失败都是因为对手使用了克苏恩这张牌,所以他想找到一些方法来抵御克苏恩.他去求助职业炉石传说玩家椎名真白,真白告诉他使用奴隶主这张牌就可以啦.如果你不明白我上面在说什么,不必担心,小Q同学会