达成三个单周坚持写博客成就(555因为双周都没写orz)
进度依然慢…
cf-Card Game
题意:博弈问题 给个n即n张牌(由1到n)每个人分n/2张 从Alex开始出牌 后手一定要比先手出的牌大 接u着Boris出 到谁出不了了就输了 求Alex赢、Boris赢和平局的分牌方式
求解:从最大的四张开始分 A先手 所以A赢就有两种 要么最大的在A 如果最大在B 那剩下的n-1和n-2必须在A n-3在A A赢 n-3不在 这四张牌平局 因而递归下去
由此可得f[n]=C(n/2-1,n-1)+C(2/n-3,n-4)+f[n-4]的递归公式 四张四张求解即可
写这题的时候思维很凝固的感觉 感觉还是要从NP开始想 觉得我的思考很没有条理性
还要注意一点 有取模和减法一起出现的时候 为了防止出现负数 要+MOD再%MOD
贴一个求组合数的板子(n比较小的情况)
1 | void C() |
cf-Reset K Edges
题意:给n个结点 以及他们的深度(1的深度是0)还可以进行k次操作 一次操作:删掉一条边 将剩下的连到1的下面去 问最多经过k操作后的最小的树的深度
求解:二分+贪心 从下向上遍历 到了高度为mid-1的那一层 如果是根节点 那么不用动 但如果不是 就把这棵子树接到1上 记录进行的操作次数与k对比 注意为了做到无后效性 要从下向上遍历
cf-1250J
题意:有一群人 要站队 给个n 给个k n表示有n个不同的身高 (全部的身高从1-n) k表示要站几排 然后会依次给出每个身高下有多少个人 站队要求:一排里面两人身高最多相差1cm 求最后的方针里最多有多少个人
求解:求最大最小值的问题自然想到二分 这题是一个二分+一点贪心 总体框架没什么问题 在站队的贪心上出了点问题 应该是从小到大依次看这个身高能组成多少队列 然后从后一个身高里取一部分人恰好凑成新的一列 这样的贪心才是最优的(搞不懂我怎么想的 就不写错误思路了)
arc146-B Plus and AND
题意:n m k n个数 能给他们加m个1 问选k个数 进行与运算(e.g 011 AND 101=001)的最大值
求解:位运算的问题 从高位到低位贪心 如果m能够使得 k个数字这一位都为1 就消耗掉 如果不能 就继续向下贪心(因为只要有1个0 与运算后就都为0了)从31跑到0 一位一位判断
其实感觉这题思路倒是很好理解 就是代码好难写哦(我太菜了)
贴个代码吧
1 | for(int i=31;i>=0;i--)//从高位到低位贪心 |
zls说位运算就要么从高位到低位想 要么从低位到高位想
牛客-跳石头
题意:给L N M 分别表示起点到终点的距离 起点和终点之间的岩石数 以及组委会至多移走的岩石数 求最短跳跃距离的最大值
求解:经典二分 通过mid看需要移走几块石头
贴个check代码
1 | int cnt=0; |
牛客-数字组合
题意:给四个数组 问每个数组取一个数字 四个数字和为0 有多少种取法
求解:一个时间复杂度上的优化 先两两加一下组成两个新的数组 然后二分查找一下
牛客-[CQOI2010]扑克牌
题意:有n种牌 每种牌张数不一样 还有m张joker n张不同的牌可以凑成一副牌 但是每副牌里不能出现相同的牌(即joker最多可以代替一张普通牌)问最多多少副牌
求解:还是二分 判断要补多少张joker(注意不能超过mid) 注意开long long
1 | int s=0; |
牛客-K-th Number
题意:A数组有n个数 给了个k 将所有大于等于k的区间中的第k大的数放入B数组中 然后问B中第m大的数是哪个
求解:这题很难想到是二分(如果没出现在题单里我肯定想不到)找出所有区间中包含大于等于k个大于等于mid的区间的数量 check函数不太好写 看到很牛的代码 用数组s去记录从1开始大于等于mid的数字数量 然后从第k个数开始遍历 如果(l-i)区间满足条件 那么l之前的更长的区间必定满足条件 所以sum+=l即是目前为止满足条件的区间数
整个思维的转换很有意思
1 | int sum=0; |
总结
先写这么多 感觉最近整个思维出现很紊乱的状态 下周开始复习一些基础的东西+过一遍贪心