2019.09.11【NOIP提高组】模拟 A 组

这次比赛做的太差了,几乎每道题都没有想到该得的分。

T1:这一题可以分开处理前后两部分。

对于k<=5*10^5的部分,暴力模拟就好了。

对于k<=100的部分,我们用状压dp。设f[i][j][s]表示完成前i道题,i+1道题减的是c[j],当前已喝的饮料集合位s的最大得分。

那么枚举一下接下来做i+1道题时的饮料集合s1来转移就好了。

总结:这题我的读题出现了问题,我认为每道题可以以任意顺序来做,但是实际上只能以给出顺序。这一点是看样例解释时可以发现的,但是我没有注意到。以后遇到这种复杂的题目要认真读题,每一个条件都要找到出处。

T2:这题也有点失误,我本来可以拿70分的。

首先设f[i][j]表示i个桶放j个球的方案数的dp大家都能想出来。但是我没有想到可以在处理T个询问之前可以预处理出f的值,然后在询问时直接调用。

正解是找规律:ans=C(n,m)^2*m!。证明可以用数学归纳法。

首先f[r][r]=C(r,r)^2*r!=r!显然,然后我们可以退出f[r+1][r]、f[r+2][r]成立。具体推法就是f[n][m]实际上表示的是在n*n的棋盘里放m个车,使得其不能互相攻击的方案数。

总结:以后遇到这种T很大,每次询问又只有n、m两个数的题,一定是找规律。在找规律时,可以与2的次幂、阶乘、杨辉三角等联系起来。

T3:首先我们发现对于一个点来说,它有1/size的概率使得它对答案的贡献为p(size表示以它为根的子树的大小),剩下(size-1)/size的概率对答案的贡献为1。这时因为一个点只有1/size的概率是它的子树中编号最小的。

这就是说我们确定了root之后把所有点的(p/size+(size-1)/size)乘起来,就是这个root的答案。

但是每一个点都有可能为root,关于这个我们可以dfs一遍来换根就好了。

注意换根时有可能除以一个在mod意义下为0的数。要解决这个问题,我们可以在乘的时候记录一个乘了几个0,然后如果要除以0,那么就减去当前0的个数即可。

发布了149 篇原创文章 · 获赞 24 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/chiyankuan/article/details/100784551