ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

和最接近某个数的子集

2022-07-06 23:00:41  阅读:188  来源: 互联网

标签:前缀 删除 加入 元素 枚举 全选 子集 某个 接近


对于整数集合 \(S\),最大元素为 \(m\),则可以在 \(m|S|\) 时间内求出和最接近某整数 \(C\) 的子集,在元素不大时比暴力背包优。做法如下:

将 \(S\) 看作一个序列并选择一个最长前缀 \(b\),满足和小于 \(C\)。

为了减小值域,考虑一种简单的方法可以使中间结果始终在 \([C - m, C + m]\) 内,并导出一个 DP。

设最优答案为 \(X\),当前答案为 \(A\)。

现在加入元素 \(i\),若 \(i \not \in X\),则不操作,否则尝试将 \(i\) 加入 \(A\),并保持和在 \([C - m, C + m]\) 内。如果可以加入就直接加入,否则不断删除标号最大的不在 \(X\) 中的元素 \(j\),直到可以加入。不难发现这样一定可以将 \(A\) 最终变成 \(X\),并且只需要维护 \(A\) 的最长全选前缀,而非整个集合 \(A\)。

设 \(f(i ,s)\) 表示前 \(i\) 个元素,表示出和 \(s\),最长全选前缀是多少。初始为 \(f(b, \sum_{i \le b}S_i) \gets b\)。

先做加入 \(i\) 的转移,再做枚举 \(f(i, s)\) 前缀中一个数删除的转移。注意如果枚举删除 \(k \le f(i - 1, s)\),那么 \(k\) 可以在 \(i - 1\) 时刻删除,这次就不用枚举了。所以对于每个 \(s\),\(k\) 的枚举总和是 \(O(|S|)\) 的,所以总复杂度 \(\mathcal O(m|S|)\)。

标签:前缀,删除,加入,元素,枚举,全选,子集,某个,接近
来源: https://www.cnblogs.com/RiverHamster/p/pseudo-polynomial-partition-problem.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有