1 条题解
-
0
核心思路
1. 关键变量定义
设 (整个序列中 1 的个数)。
根据定义: [ b_1 = 0 - S = -S ] [ b_{n+1} = S - 0 = S ] 所以: [ b_1 = -S,\quad b_{n+1} = S ]
误差限制: [ |b_1 - c_1| + |b_{n+1} - c_{n+1}| = |-S - c_1| + |S - c_{n+1}| \leq k ] 这给出了 的可能范围。
2. 递推关系
设 (前 项中 1 的个数),则: [ b_i = p_i - (S - p_i) = 2p_i - S ] 所以: [ p_i = \frac{b_i + S}{2} ]
由于 必须是整数且 ,。
3. 动态规划解法
代码使用滚动数组 DP,状态为:
stk[u][j]:存储可能的 值(偏移后的状态)val[u][j]:存储对应的累计误差pre[i][x]:记录前驱选择(0 或 1)
状态转移: 设当前状态 (加 是为了保证非负), 选择 或 时:
- 若 ,则 ,
- 若 ,则 ,
误差更新: [ \text{new_error} = \text{old_error} + |b_{i+1} - c_{i+1}| ] 若累计误差超过 则剪枝。
4. 算法流程
- 枚举 S:从 0 到 n 枚举可能的 1 的个数
- 可行性检查:
- 首先检查
- DP 过程:
- 初始化:,对应状态
- 递推:对于每个 ,尝试 或 ,更新状态和误差
- 剪枝:误差超过 的状态被丢弃
- 构造解:
- 如果找到可行解,从后往前根据
pre数组恢复
- 如果找到可行解,从后往前根据
重要公式
-
首尾约束: [ | -S - c_1 | + | S - c_{n+1} | \leq k ]
-
b_i 与 p_i 关系: [ b_i = 2p_i - S ]
-
状态表示: [ x = 2p_i - S - c_i + m ] ( 是偏移量,确保下标非负)
-
误差计算: [ \text{error} = \sum_{i=1}^{n+1} |2p_i - S - c_i| ]
复杂度分析
- 枚举 :
- 每个 的 DP:状态数受 限制,为
- 总复杂度: 最坏,但实际剪枝很有效
- 1
信息
- ID
- 3969
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 5
- 已通过
- 1
- 上传者