布尔括号问题是计算给定二进制表达式括起来的方式的数量,以便它的计算结果为true。
我根据给出here(small video explanation here)的解释编写了一个C ++解决方案,但它总是返回零。我的代码看起来与第一页上给出的代码非常相似(在编写我的代码之前我没有看过),但它适用于我的代码。我犯了什么错误?
#include <iostream>
#include <vector>
#include <map>
#include <queue>
#include <algorithm>
using namespace std;
int main() {
int n;
cin >> n;
vector<int> vals(n);
vector<int> ops(n - 1); //ops[n] is the operator
//between the nth and (n-1)th values
char tmp;
for(int i = 0; i < 2 * n - 1; ++i) {
if(i % 2 == 0) {
cin >> vals[i / 2];
} else {
cin >> ops[i / 2];
}
}
vector<vector<int> > t(n, vector<int>(n, 0)),
f(n, vector<int>(n, 0));
for(int i = 0; i < n; ++i) {
t[i][i] = vals[i] == 1;
f[i][i] = vals[i] == 0;
}
const int AND = 6, OR = 1, XOR = 4;
for(int i = 0; i < n - 2; ++i) {
for(int j = i + 1; j < n - 1; ++j) {
for(int k = i; k < j; ++k) {
cout << endl << i << " " << j << " " << k << endl;
switch(ops[k]) {
case AND:
t[i][j] = t[i][k] * t[k + 1][j]; //T & T = T
f[i][j] = f[i][k] * f[k + 1][j] //F & F = F
+ f[i][k] * t[k + 1][j] //F & T = F
+ t[i][k] * f[k + 1][j]; //T & F = F
case OR:
t[i][j] = t[i][k] * t[k + 1][j] //etc
+ f[i][k] * t[k + 1][j]
+ t[i][k] * f[k + 1][j];
f[i][j] = f[i][k] * f[k + 1][j];
case XOR:
t[i][j] = f[i][k] * t[k + 1][j]
+ t[i][k] * f[k + 1][j];
f[i][j] = f[i][k] * f[k + 1][j]
+ t[i][k] * t[k + 1][j];
}
for(int i = 0; i < n; ++i) {
for(int j = 0; j < n; ++j) {
cout << t[i][j] << " ";
}
cout << endl;
}
} //k loop
} //j loop
} //i loop
cout << endl << t[0][n - 1];
}
答案 0 :(得分:0)
外部的两个循环(i
和j
)不正确。您在代码中执行的操作是从表达式的一端开始,向另一端(i
循环)移动,并尝试计算从当前位置开始的越来越宽的子表达式(width { {1}},j - i
循环)。问题在于,为了计算宽度为j
的表达式的括号变体,您需要宽度为k
且更小的子表达式的所有值,在您的解决方案中,您需要使用#39} ; t计算了(不管怎样,不是全部)。因此,您依赖于尚未计算的值并默认为k - 1
,这会在这些乘法中为您提供很好的胖零。
与任何动态编程问题一样,诀窍是只有在计算了宽度0
的所有相关值之后才构建宽度k
的所有值。所以,外部的两个循环看起来应该是这样的:
k - 1
请记住,这是未经测试的,未实现的代码,它只是基于我对这种情况下的动态编程问题的理解(我的理解已经被认为是错误的。时间...)。但是,它应该让你在清理工作方面有一个良好的开端。