1 条题解
-
0
「巴厘岛的雕塑」题解
问题分析
给定 个雕塑的年龄 ,需要将它们分成恰好 组(),每组连续。每组的年龄和进行按位或运算,得到最终优美度。要求最小化这个优美度。
关键观察
- 位运算性质:按位或运算只会使数值增大或不变,不会减小。
- 最小化思路:从高位到低位考虑,尽可能让最终优美度的每一位为 。
- 二分答案可行性:由于答案范围可达 级别,直接枚举不可行,考虑按位确定答案。
算法框架
对于小数据,可以采用DP + 按位贪心的方法:
-
从高到低逐位确定:
- 从最高位(如第60位,因为总和可能很大)开始考虑
- 对于当前考虑的位 ,我们希望最终优美度的这一位为
-
DP验证可行性:
- 设当前已经确定了高位的一些位为 ,这些位构成一个掩码
- 我们需要判断:是否存在一种分组方式,使得: a) 组数在 之间 b) 每一组的和与 的按位与为 (即不包含已经确定为 的位) c) 每一组的和在第 位也为
-
DP状态设计:
- :表示考虑前 个雕塑,分成 组是否可行
- 转移:$dp[i][j] = \bigvee_{l<j} (dp[l][j-1] \text{ and valid}(l+1, i))$
- 其中 表示区间 作为一组是否满足上述条件
-
时间复杂度:,优化后可达
当 时,问题简化为:最少分组数没有下限,只需要不超过 组。
-
同样从高到低逐位确定
-
使用一维DP:
- :表示前 个雕塑最少需要多少组
- 转移:,其中区间 满足条件
- 最终检查 是否成立
-
优化:
- 前缀和加速区间和计算
- 时间复杂度:,对于 可能较慢
- 可以进一步优化到 ,通过记录可行的转移位置
算法步骤详解
步骤1:预处理前缀和
计算 ,方便计算任意区间和。
步骤2:逐位确定答案
初始化答案 。
从高位到低位(如从60到0):
- 尝试将当前位设为 :(即当前位为0,低位全1)
- 用DP验证是否存在分组,使得所有组的和按位与 等于自身(即不含 中为0的位)
- 如果存在,则这一位可以设为0,否则必须设为1,更新
步骤3:DP验证函数
对于一般情况():
function check(mask): dp[0][0] = true for i = 1 to N: for j = 1 to min(i, B): dp[i][j] = false for l = j-1 to i-1: if dp[l][j-1] and ((pre[i]-pre[l]) & mask) == (pre[i]-pre[l]): dp[i][j] = true break 检查是否存在 A ≤ j ≤ B 使得 dp[N][j] = true对于 的情况:
function check(mask): dp[0] = 0 for i = 1 to N: dp[i] = INF for l = 0 to i-1: if ((pre[i]-pre[l]) & mask) == (pre[i]-pre[l]): dp[i] = min(dp[i], dp[l] + 1) 返回 dp[N] ≤ B步骤4:边界情况处理
- 当 时,可以每个雕塑单独一组
- 当 时,必须恰好分成 组
- 注意 可能为0
复杂度分析
:,其中 为值域, 可过 , 需要优化
优化技巧
- 对于 的情况,可以使用单调队列或贪心优化到
- 提前剪枝:如果当前位必须为1,则直接设置,不需要DP验证
- 使用位运算加速条件判断
算法正确性证明
- 从高到低贪心的正确性:由于高位为1对数值的影响远大于低位,优先保证高位为0是最优策略。
- DP验证的正确性:DP准确刻画了分组问题的约束条件,验证了在当前掩码下是否存在合法分组。
- 最小性保证:通过从高位到低位尽可能置0,得到的答案是最小的。
实现注意事项
- 数据类型:使用64位整数,因为总和可能超过32位。
- DP初始化:注意边界条件的设置。
- 位运算优先级:注意括号的使用。
- 前缀和索引:, 表示前 个数的和。
总结
本题的核心思想是:
- 按位贪心:从高位到低位确定答案
- DP验证:判断在当前位限制下是否存在合法分组
- 分类处理:根据 是否为1采用不同的DP方法
- 1
信息
- ID
- 5861
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者