问题描述:
对于一个只由0(假)、1(真)、&(逻辑与)、|(逻辑或)和^(异或)五种字符组成的逻辑表达式,再给定一个结果值。现在可以对这个没有括号的表达式任意加合法的括号,返回得到能有多少种加括号的方式,可以达到这个结果。
给定一个字符串表达式exp及它的长度len,同时给定结果值ret,请返回方案数。保证表达式长度小于等于300。为了防止溢出,请返回答案Mod 10007的值。
测试样例:
"1^0|0|1",7,0
返回:2
AC代码:
class Expression {
public:
static const long long MOD = 10007;
int countWays(string exp, int len, int ret) {
// write code here
if (len == 0) return 0;
if (!isValid(exp, len)) return 0;
bool desired = ret?true:false;
long long t[len][len]; // true表
long long f[len][len]; // false表
memset(t,0,len*len*sizeof(long long));
memset(f,0,len*len*sizeof(long long));
for (int i = 0; i < len; i += 2) {
t[i][i] = exp[i] == '1'? 1 : 0;
f[i][i] = exp[i] == '0'? 1 : 0;
for (int j = i-2; j >= 0; j -= 2) {
for (int k = j; k < i; k += 2) {
if (exp[k+1] == '&') {
t[j][i] += ((t[j][k]*t[k+2][i]) % MOD);
f[j][i] += ((f[j][k]*t[k+2][i]) % MOD + (t[j][k]*f[k+2][i]) % MOD + (f[j][k]*f[k+2][i]) % MOD);
}
else if (exp[k+1] == '|') {
t[j][i] += ((f[j][k]*t[k+2][i]) % MOD + (t[j][k]*f[k+2][i]) % MOD + (t[j][k]*t[k+2][i]) % MOD);
f[j][i] += ((f[j][k]*f[k+2][i]) % MOD);
}
else {
t[j][i] += ((t[j][k]*f[k+2][i]) % MOD + (f[j][k]*t[k+2][i]) % MOD);
f[j][i] += ((t[j][k]*t[k+2][i]) % MOD + (f[j][k]*f[k+2][i]) % MOD);
}
}
}
}
return (desired?t[0][len-1]:f[0][len-1])%MOD;
}
bool isValid(string exp, int len)
{
if (len & 1 == 0) return false;
for (int i = 0; i < len; i += 2) {
if (exp[i] != '1' && exp[i] != '0') return false;
}
for (int i = 1; i < len; i += 2) {
if (exp[i] != '&' && exp[i] != '|' && exp[i] != '^') return false;
}
return true;
}
};