:已知,用于求解中的某一组解 ;而求 的解,只需要将 求出的 同时乘上 即可。
具体题解:

code
被复杂题意包装起来的01背包。
简化一下题意就是:有个物品,背包体积为,第个物品的体积为,且有种价值,其中只有一种价值对应“全部升级”(价值为),剩下种价值对应“部分升级”(价值对应)。可以选择至多一个物品“部分升级”,其他必须为“全部升级”。设选取的“全部升级”的物品总体积为,则“部分升级”物品的价值为。求可获最大价值。
可以将物品的个价值看做:物品的体积为时(),价值为(可以证明这种定义方式与题意等价)。这样,就规定选取的物品存在“部分升级”时,总价值必须恰好为。因此在初始化数组时必须为(对于未规定选取恰好体积时初始化为)。
特点在于,且至多只能有一个“部分升级”的物品。所以状态可设置为:
:考虑前个物品,选取物品的总体积为,且选了个“部分升级”的物品,最大总价值。
可以直接暴力枚举“部分升级”物品的所有价值并转移,转移时对于第种物品,考虑种情况即可:
- 不选第个物品(不代表真的不选,而是作为题中的那部分,价值为 地选择该物品,相当于不选。这里容易混淆)-> 从前缀的状态转移
- 第个物品“全部升级” -> “部分升级”的状态均能转移
- 第个物品“部分升级” -> 由于最多只能选一个,则只能从已选“部分升级”的 状态转移
注意当特别大时,所有物品不能装满背包,这时所有物品必须均为“全部升级”状态。而只处理了选取恰好体积的情况,故需要特判很大的情况。(如果不特判,而是采用枚举的方式更新答案,则会有一种情况导致错误:某个物品“部分升级”比“全部升级”的价值更大,导致对这个物品进行选择时,在背包体积足够时,选了该物品“部分升级”的情况。虽然这样的情况答案更优,但却是不合法的,因为在背包体积足够的情况下,所有物品必须“全部升级”。具体见WA on 7)
可以倒序枚举体积,省去01背包数组中物品个数的那一维。
具体实现见代码
复杂度
ACcode
WA on 7
字典树
考虑逆序对的贡献是怎样产生的。
分析后可发现,逆序对产生的方式有两种:
- 两个字符串的前个字符相同,第个字符不同
- 一个字符串是另一个字符串的前缀
设表示在给定的字符串序列中,对的数量,其中满足:
- 在 之前
- 存在一个位置 ,使得
- ,。表示字符。
则
其中为字符在当前给定的字母表中的位置。
计算:在插入某个字符串前,用这个字符串跑一遍字典树,若可到的末尾,则看其末尾之后的前缀数量,这些字符串都可以使得是它们的真前缀,自然和构成逆序对。对于每个字符串,在插入前做这样的统计即可。注意走不到末尾时不能作统计,具体实现见代码。
code
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战