2024/12/16 总结
背包问题(knapsack)
背包问题是一类已经被研究的比较透彻的问题, 在这道题中你需要考虑背包问题的 一个变种. 你现在有三个背包, 容量分别为 𝑉1,𝑉2,𝑉3. 你还有许多物品, 每个物品以一个三元组 (𝑤𝑖,1,𝑤𝑖,2,𝑤𝑖,3) 的格式给出. 对每一个物品, 你可以选择一个背包将这个物品放进去. 如 果你选择将其放入第 𝑗 个背包, 则会消耗第 𝑗 个背包 1 的容量, 同时获得 𝑤𝑖,𝑗 的价值. 现在总的物品数量恰为 𝑉1+𝑉2+𝑉3, 你需要找出一种将所有物品放进背包的方案, 使得 最终获得的总价值最大.
slove1
六个堆贪心,先把三个背包随便装满。然后建立六个堆,分别表示从背包1到背包2(存储背包1中的所有元素),背包1到3(存2的所有元素,其他同),2到3,2到1,3到1,3到2的答案变化。
即6个堆分别存将背包x的所有元素从背包x[1 , 3]移动到背包y[1, 3]的答案变化。
大根堆。如果x到y的堆根和y到x的堆根和是正的,就代表交换是优的,我们就交换,同时更改六个堆中的元素(增加或删除),一直做直到没有两个有关系的堆堆根和是正的了,当前解就是最优的了。
slove2
假设将三元组全部放在一个背包,然后要取出v2个放在背包2,取出v3个放在背包3.
然后问题就变为在n个二元组(b-a,c-a)中选(其他条件如题)
把这些二元组按照first-second排序,如果前面的放在背包2,后面的放在背包1,可以证明交换后解会优。
所以一定存在一个分界点,在他前面选前v1个较大贡献值放在背包1,后面的选前v2个较大贡献放在背包2.
枚举分界点,然后就做完了。
游戏(game)
Alice 和 Bob 在做游戏. 现在有一个 1×𝑛 的棋盘, 其上第 𝑖 个格子有正整数 𝑎𝑖. 有一个棋子初始在 𝑠 处. 现 在 Alice 和 Bob 交替操作, Alice 先手: 如果当前棋子在 𝑝 处, 则玩家可以选择 •将 𝑝 加上最少 1, 最多 𝑘 (不能让 𝑝>𝑡). •如果 𝑎𝑝>0, 给 𝑎𝑝 减 1 其中 𝑘 是给定的参数, 𝑡 是棋子的终点. 不能操作的玩家失败. 在这个游戏的基础上, 你需要维护 𝑞 次操作, 每次操作可以 1.给定 𝑙,𝑟,𝑑, 将区间 [𝑙,𝑟] 中的 𝑎𝑖 全部加上 𝑑. 2.给定 𝑠,𝑡, 查询以 𝑠 为起始点, 𝑡 为结束点的游戏中, 谁会获胜
结果是必败态。
当一个玩家认为当前往后直接走会必败的时候,他一定会选择将当前ai减一交给对手,但是对手在ai为偶数的时候显然会不让他这么做,必败的结果不会改变,所以:
所以 𝑎𝑖 =1 为先手必胜的状态; 𝑎𝑖 =0 的状态需要看后 𝑘 个位置当中有没有先手必 败的状态
然后稍微转换一下就变成了[弹飞绵羊]([P3203 HNOI2010] 弹飞绵羊 - 洛谷 | 计算机科学教育新生态)
把序列分块,
维护to[i]表示跳出所在块后的位置,这样的话判断结果就是根号的。
修改的话就暴力重构块。
重 要 的 经 验
永远不要同时使用__gnu_pbds和std命名空间,你永远不知道会发生什么!!!!!!
再也别写六个堆反悔贪心了,调不出来的