【题解】2019ZJOI浙江省选day1

T1  麻将-题解

大概思路是,先考虑怎么判断一个集合有没有胡的子集,第二种情况只需求出cnt[i]>=2的i的个数,第一种情况可以dp,dp[i][0/1][j][k]表示考虑大小为1...i的牌,有/没有选对子,选了j个面子,cnt[i]还剩k,cnt[i-1]的最大值。然后回到原问题,dp[i][S]表示考虑完大小为1...i的牌每个大小选几张,当前集合可以用S描述,当前集合不存在子集是胡的的方案数。则答案就是 ,因为考虑一个排列,如果他在第i位第一次存在子集是胡的,则他会被计算i次。

能写出来就有90分。实际上由于状态数不满,加一些剪枝之后第二维只有1e5左右,可以通过此题。

#T1代码戳#


T3  Minimax 搜索-题解:

考虑对于每个 求出有多少个 ,则可以通过差分得到答案。

先考虑给定S,R如何判断w(S)是否 。考虑根节点的权值如果可以变大,则一定可以变成W+1,如果可以变小,则一定可以变成W-1。因此树形dp,用 f_i,g_i 分别表示考虑结点i的子树,i的权值能否变成W+1,W-1。时间复杂度 O(n)

再来考虑给定R,如何求出有多少个dp(i,a,b) 表示考虑i的子树,有多少个选择叶节点的方案使得 (可以看作是dp套dp)。时间复杂度 O(n)

回到原问题,考虑从小到大枚举R,则每次只有至多两个叶节点的dp信息可能发生变化,因此可以动态dp维护。这样需要维护4*4的矩阵的乘积,不仅有4^3的常数大概率会导致TLE,而且实现起来也很麻烦。

请教@lyx-cjz(比赛时唯一一个ac,orz)后知道了一个更优越的做法。

还是先考虑给定S,R如何判断w(S)是否 。如果S包含W,则一定可以(当然 显然无论如何都不可以);否则,考虑如果想让根节点的权值变大,原来就>W的结点显然不用变,原来<W的结点能变成W+1就变成W+1;类似的,如果想让根节点的权值变小,原来就<W的结点显然不用变,原来>W的结点能变成W-1就变成W-1。因此 等价于 。因此只需要分别做一遍dp即可,具体的dp和上面是类似的。

再来考虑给定R,如何求出有多少个 。只需要用总方案数减去>R的,而这只需对x>W,x<W的集合分别求出>R的方案数,然后相乘即可。以x>W为例,只需 f_i 表示 i 的权值<W的方案数。

这样就可以轻松的使用动态dp优化了。

关于具体实现,首先用 f_i 表示 i 的权值<W的概率,而不是方案数,但这样转移需要分深度奇偶讨论,因此令 ,就可以去掉讨论,得到一个非常简单的转移式:

#T3代码戳#


全部评论
前排兹瓷&&Orz kcz
点赞 回复 分享
发布于 2019-04-03 09:20

相关推荐

02-25 11:29
产品经理
牛客444597598号:兄弟 我只能说如果想找产品经理这种简历 基本就是毕业失业了 你这连实习都找不到的 简历跟产品经理一点都没有关系,你可以去搜搜产品的模版吧
点赞 评论 收藏
分享
03-15 12:48
门头沟学院 Java
牛牛要早起:这个一般就跟你说有高薪,然后叫你买车,之后血亏
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务