布尔括号化问题(带符号权重版本)
题目描述
给定一个布尔表达式字符串,其中只包含三种字符:'T'(真)、'F'(假)和运算符('&'(与)、'|'(或)、'^'(异或))。表达式由符号和运算符交替组成,例如 "T|F&T^F"。每个符号 T 或 F 附带一个正整数权重值,权重数组与符号顺序对应。求通过不同括号化方式,使表达式最终结果为 T 的所有方法中,总权重最大的值(总权重定义为最终结果为 T 的括号化方案中,所有符号的权重之和)。
示例
表达式:"T|F&T",权重:[2, 1, 3]
- 括号化方式1:
(T|F)&T→(T|F)为T,再与T得T,总权重 = 2+1+3=6 - 括号化方式2:
T|(F&T)→(F&T)为F,再与T得T,总权重 = 2+1+3=6
最大总权重为 6。
解题步骤
1. 问题分析
- 表达式形式为:
符号 运算符 符号 运算符 ... 符号(长度必为奇数)。 - 目标:最大化使表达式为
T的括号化方案的总权重(即所有符号权重和,因为括号化不改变符号)。 - 关键:需要同时跟踪布尔结果(T/F)和对应的最大权重,因为不同括号化可能产生相同的布尔结果但权重不同。
2. 定义DP状态
设 dp[i][j][0] 表示子表达式 s[i:j](包含两端)通过括号化得到结果 F 的最大权重;
dp[i][j][1] 表示得到结果 T 的最大权重。
若子表达式无法得到某种结果,则对应值为 -∞(无效状态)。
3. 状态转移方程
-
基础情况:当
i == j(单个符号)时:- 若
s[i] == 'T':dp[i][j][1] = weight[i],dp[i][j][0] = -∞ - 若
s[i] == 'F':dp[i][j][0] = weight[i],dp[i][j][1] = -∞
- 若
-
对于长度大于1的区间
[i, j],枚举分割点k(k为运算符位置,从i+1开始,步长为2):
将表达式分为左部分[i, k-1]和右部分[k+1, j],运算符为op = s[k]。
根据运算符的真值表组合左右部分的布尔结果:op = '&':- T & T → T:
dp[i][j][1] = max(dp[i][j][1], dp[i][k-1][1] + dp[k+1][j][1]) - 其他组合(T&F, F&T, F&F)均得 F:更新
dp[i][j][0]
- T & T → T:
op = '|':- T|T, T|F, F|T → T:更新
dp[i][j][1] - F|F → F:更新
dp[i][j][0]
- T|T, T|F, F|T → T:更新
op = '^':- T^F, F^T → T:更新
dp[i][j][1] - T^T, F^F → F:更新
dp[i][j][0]
- T^F, F^T → T:更新
4. 计算顺序
按区间长度从小到大计算:
长度 len = 1, 3, 5, ..., n(n 为表达式长度)。
5. 最终结果
答案为 dp[0][n-1][1](整个表达式结果为 T 的最大权重)。
示例详细计算
表达式:"T|F&T",权重:[2, 1, 3],索引 0~2。
-
初始化单个符号:
dp[0][0][1] = 2(T),dp[0][0][0] = -∞dp[1][1][0] = 1(F),dp[1][1][1] = -∞dp[2][2][1] = 3(T),dp[2][2][0] = -∞
-
长度3的区间
[0,2]:- 分割点
k=1(运算符'|'):
左:[0,0](T),右:[2,2](T)
T|T → T:dp[0][2][1] = max(-∞, 2+3) = 5
其他组合不产生 F(此处无 F|F)。 - 分割点
k=1已覆盖所有可能。
最终dp[0][2][1] = 5,dp[0][2][0]无有效值。
- 分割点
-
最终结果:
dp[0][2][1] = 5(但示例中答案为6?需检查)。
修正:
示例中两种括号化均得到 T,总权重均为 2+1+3=6。问题在于:总权重是固定的(所有权重和),与括号化无关?
仔细读题:总权重是所有符号的权重之和,确实与括号化无关。但若所有权重和固定,则最大权重就是权重和,问题退化。
可能题目意图是:求所有使表达式为 T 的括号化方案中,符号权重和的最大值,但权重和固定,因此只需判断是否存在使表达式为 T 的括号化,若存在则答案为权重和,否则为0。
但示例中答案应为6,而非5。说明原示例计算有误:
- 正确计算:表达式
"T|F&T"权重和=2+1+3=6,只要存在一种括号化使结果为 T,答案就是6。 - 验证:
(T|F)&T = (T|F)→T, T&T→T;T|(F&T)=T|F→T。存在方案,故答案为6。
结论:若题目中权重和固定,则问题简化为先判断是否存在结果为 T 的括号化(布尔括号化原问题),若存在则输出权重和,否则输出0。DP状态可简化为记录布尔值是否存在即可。