题目
下图所示的三角形中,有14个“+“和14个“-”。2个同号下面是**+**,两个异号下面是 -。
在一般情况下,符号三角形的第一行有n个符号。符号三角形问题,要求对于给定的n,计算有多少个不同的符号三角形,使其所含的“+”和“-”相同。
题解
采用子集树回溯模型
backtrack(int t) //搜索到树的第t层
1. 若 t>n, 判断 记录 返回
2. 对 i = 0 : 1
3. | 若 满足 Constraint(t) 和 Bound(t)
4. | 则 backtrack(t+1);
剪枝函数
- 符号总个数必须为偶数
- 当加号或减号的总数超过总数的半时停止搜索
代码如下
void backtrack(int t)
{
/* Count 当前三角形中加号1的个数
* half 总符号数的一半
* sum 符合条件的三角形个数
*/
if( (Count > half )|| ((t-1)*t/2-Count>half)) return ;//剪枝
if (t > n) sum++;
else {
for(int i = 0; i < 2; i++)
{
p[1][t] = i;Count+=i;
for(int j = 2; j<=t;j++)
{
p[j][t-j+1] = p[j-1][t-j+1] ^ p[j-1][t-j+2];
Count+=p[j][t-j+1];
}
backtrack(t+1);
for (int j = 2;j<=t;j++)
{
Count-=p[j][t-j+1];
}
Count-=i;
}
}
}