假面

这道题目我维护每个回合每个人的每种血量的概率想到了,甚至DP也想到了,但是这个DP的方法太新了

因为本来维护每个回合每个人的每种血量的概率后,我们如果用组合数去选出若干个人计算概率,肯定时间复杂度太大了,这个时候我们一般都是用DP去统计满足条件的概率,所以要用DP,而且比较容易想到要计算g[i][j]表示第i个人以及其余还有j个人活着的概率(但是将第i个人放在最后,这确实是非常新的思想了,可以记住)

见这篇题解

一些解释:

f[i][j]涉及的i个人是某一次使用结界技能时题目给出的k个人(而不是全部n个敌人)

文章中说“f[k1]就是g[i]”的意思是f[k1][j]=g[i][j]

复杂度O(n3)怎么算出来的:枚举每一个i,将其放在最后,然后计算f,一共是O(nn2)=O(n3)

最后倒着求那里,f[k1][j]不应该放在分子那里,应该是f[k1][j]等于后面那一坨分数;至于倒着求怎么想到的,我们最开始利用了换序来考虑整体,所以整体是不变的,可以考虑利用这个不变量

update 2024.5.4

自己独立做出来啦,所以要相信自己呀

首先来看第二问吧,根据我们对期望的理解(这个理解具体见罗森的离散数学教材),直接暴力DP每个时刻每个人不同血量的概率就好了(由于题目求的期望只针对每一个人,所以我们一个人一个人地考虑,对于一个人,实验就是其所有时刻的血量,一个实验的子实验就是其各个时刻的血量)

然后是第一问,就像先前所说的一样,用组合数的话时间复杂度太大了,此时考虑DP,我们现在要知道的信息就是被选中的k个人中有j个人还活着的概率,所以设f[i][j]表示前i个人活着j个人的概率是多少(跟题解里面的一样,注意题解里面有alive+dead=1;然后具体写代码的时候也可以把不是这k个人里面的人考虑进来,只不过不影响答案,有f[i][j]=f[i1][j]而已);然后由于所有人是独立的,现在我们要确定一个具体的人活着且其他若干个人活着的概率,可以考虑将我们确定的这个人放在最后用类似的过程DP,但是这样肯定会超时间复杂度,所以我们先写出式子,有f[n][j]=alive×(j1)+dead×(j),那么0个人活得glv我们是可以直接计算得到的,所以我们可以将括号中的概率求出来(注意一个细节,如果某个时刻dead为0要特殊考虑)

update 2024.8.11

一般遇到这种有一个特殊元素的,我们考虑枚举特殊元素,然后单独考虑其左边和右边的DP,再尝试合并,但是这里这么做仍然会超时;所以另一种解决方案就是利用整体与个体的关系去进行推导,这个也要记住

posted @   最爱丁珰  阅读(8)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示