20210629模拟

感觉今天的题解是大工程

T1

这道题的40分我觉的还是很好理解的,100分可能我自己理解的也不是很到位把,就是大致讲一下

40pts:

先定义几个状态:

f[i][j]表示恰好有i个人喜欢假钞j的概率

h[i][j][k]表示前i个人恰好有j个人喜欢假钞k的概率

g[i][j]表示第i种假钞一共选了j个,这种假钞的期望拿走个数

dp[i][j]表示前i种假钞一共选了j个的期望拿走个数

转移方程:

h[i][j][k] = h[i-1][j][k]( imes)(1-p[i][k])+h[i-1][j-1][k]*p[i][k];

这个就比较显然吧,第i个人喜欢或不喜欢的概率,f[i][j] = h[n][i][j]

g[i][j] = min(j,k)( imes)f[i][k] ((0leq kleq m))

其实分为两部分,如果喜欢i的人少于j个,那么就取k,否则取j,乘上对应的概率就好

dp[i][j] = min(dp[i-1][j-k]+g[i][k])

一个简单背包

100pts:

g[i][j]-g[i][j-1] = (sumlimits_{kleq kleq n} f[i][k])这个地方题解好像打错了,我自己是推出来这个

不难发现他是非负且单调不升的,也就是说第i种假钞,选x+1个比选x个收益大,但是从x+1到选x+2个没有从x个到选x+1个增量大

所以我们每次可以贪心的选取增量最大的那个假钞,这里思路都是很明白的,那么代码怎么写呢?这也是我纠结了很久的地方

先看这部分

	rep(i, m)
	{
		dp[i][0] = 1;
		rep(j, n) dp[i][j] = dp[i][j - 1] * (1 - p[i][j]);
		dev[i] = 1 - dp[i][n];
	}

这里是在干嘛呢??对于第一次的g的差量,为(sumlimits_{1leq kleq n} f[i][k]),就是有1,2,3,一直到n个人喜欢这个假钞

正难则反,我们求出都不喜欢的概率,然后用1去减就好了

然后每次我们都相当于去掉了恰好1个喜欢,恰好两个喜欢,恰好三个喜欢……,这部分的代码:

	rep(t, n)
	{
		int x = 1;
		rep(i, m) if (dev[x] < dev[i]) x = i;
		ans += dev[x];
		rep(j, n) rec[j] = dp[x][j];
		rec[0] = dp[x][0]; dp[x][0] = 0;
		rep(j, n) dp[x][j] = dp[x][j - 1] * (1 - p[x][j]) + rec[j - 1] * p[x][j];
		dev[x] -= dp[x][n];
	}

当前的dp比上一次的喜欢人数多1,rec和上一次的喜欢人数一样,强制让当前这个人喜欢或不喜欢他

在说的清楚点是什么呢,每次转移,如果现在已经多喜欢了一个人,当前人就不能喜欢了也就是dp[x][j-1]( imes)(1-p[x][j]),如果还没有多喜欢,我就让他喜欢,rec[j-1]( imes)p[x][j]

这样我dp就可以表示出每次的差量,差量在不断累加,最后就是我该选的数量对应的贡献

发现我讲讲就讲明白了哎,我觉的这份代码是最简洁,而且我应该是把代码思路阐述的最好的一个了吧,反正其他的我都没看懂……

T2

问题可以转化成每次选出一个点,然后把他所在的联通块里的点都捶一边,求每个点被捶的期望次数之和

可以考虑一个点会在其他点被选中时的期望被捶次数,可以被捶到当且仅当两点联通

也就是说,其他点不管,被选中的点j一定是两点路径上的点第一个被删除的,概率为1/点数(强制两点间的点都没选)

我应该是(O(n^2log))的,暴力判断两两点之间的点数,不知道st表O(1)查询lca会怎么样

还有个(O(n^2))可以对每个点dfs一次,和某种换根感觉差不多,求路径的逆元和呗,第三题给我写麻了,不然应该60的

T3

感觉不是难,也不是难写,也不知道为什么代码这么长,而且luogu上交还T

两个炮台可以来回转化,但是非a即b,我们是不是就可以联想到2-SAT问题?

这样我们对于每个炮台,暴力dfs判断横向和纵向是否合法,如果都不合法就IMPOSSIBLE

对于合法的方向,我们把这个炮台塞到用他能表示的点所属的炮台集合中(集合里的炮台横向发射或纵向发射可以到达该点)

我们容易证明对于每个点,最多只有两个炮台能到达他,为什么呢??

如果有多个,证明一定有两个炮台同为横向或者纵向,按照光路可逆!证明他们俩一定会互相打到,不合法

最后如果每个点都被覆盖到,跑2-SAT,否则不合法

Day2

T1

T1真的是NOI模拟么?人均切的一道题

设dp[i][j]表示前i个蒲公英,时间为t,能的得到的最高魔法值,转移的是时候需要满足转移前的魔法值大于所需魔法值

但是前两个样例都很水,所以有个小tips,如果之前有个魔法值大的点不能满足,但是取过一些蒲公英后满足了,这个点就被我们忽视掉了

所以我们按照魔法值拍个序就好了,再就是输出方案了,我还卡了一段时间,不过还算比较简单吧

T2

暴力怎么做?

把每一次轮换都加到Trie树上,然后在Trie树上dp

优化:直接建后缀树,在后缀树上Dp,其中压在一个节点上的链可以快速处理转移

原文地址:https://www.cnblogs.com/little-uu/p/14950137.html