https://leetcode-cn.com/problems/boolean-evaluation-lcci/
思路:看数据范围应该可以暴力枚举,不过我们还是用
d
p
dp
dp吧。
d
p
[
i
]
[
j
]
[
0
]
dp[i][j][0]
dp[i][j][0]等于使
[
i
,
j
]
[i,j]
[i,j]的表达式得出
0
0
0的括号方法数,
d
p
[
i
]
[
j
]
[
1
]
dp[i][j][1]
dp[i][j][1]等于使
[
i
,
j
]
[i,j]
[i,j]的表达式得出
1
1
1的括号方法数。枚举断点
k
k
k,
s
[
k
]
s[k]
s[k]对应不同的运算符时有不同的计算方法,具体看代码。
class Solution {
public:
bool isNum(char ch){
if(ch=='0'||ch=='1')
return 1;
return 0;
}
int countEval(string s, int result) {
int siz=s.size();
vector<vector<vector<int>>> dp(siz,vector<vector<int>>(siz,vector<int>(2,0)));
//初始化
for(int i=0;i<siz;i++){
if(isNum(s[i]))
dp[i][i][0]=s[i]=='0',dp[i][i][1]=1^dp[i][i][0];
}
for(int len=3;len<=siz;len++){
for(int i=0;i+len-1<siz;i++){
int j=i+len-1;
//确保i、j位置上的是数字
if(!isNum(s[i])||!isNum(s[j]))
continue;
//k依次加2 可以确保这个位置上是运算符
for(int k=i+1;k<j;k+=2){
//或 运算符
if(s[k]=='|'){
dp[i][j][0]+=dp[i][k-1][0]*dp[k+1][j][0];
dp[i][j][1]+=dp[i][k-1][0]*dp[k+1][j][1]+dp[i][k-1][1]*dp[k+1][j][0]
+dp[i][k-1][1]*dp[k+1][j][1];
}//与 运算符
else if(s[k]=='&'){
dp[i][j][1]+=dp[i][k-1][1]*dp[k+1][j][1];
dp[i][j][0]+=dp[i][k-1][0]*dp[k+1][j][1]+dp[i][k-1][1]*dp[k+1][j][0]
+dp[i][k-1][0]*dp[k+1][j][0];
}//异或 运算符
else{
dp[i][j][1]+=dp[i][k-1][0]*dp[k+1][j][1]+dp[i][k-1][1]*dp[k+1][j][0];
dp[i][j][0]+=dp[i][k-1][0]*dp[k+1][j][0]+dp[i][k-1][1]*dp[k+1][j][1];
}
}
}
}
return dp[0][siz-1][result];
}
};