回溯法——符号三角形问题

141 阅读1分钟
  • count:'-'的个数
  • half:n(n+1)/4
  • sum:可行解的个数
  • p:存储三角形的数组
void backtrack(int t)
{
    // 无解的判断(+或-是否超过了总数的一半)
    if ((count > half) || ((t * (t - 1) / 2 - count) > half))
        return;
    if (t > n)
        sum++;
    else
    {
        for (int i = 0; i < 2; i++)
        {
            p[1][t] = i; // i=0的时候,放一个'+',因为'+'用0代替;i=1的时候,放一个'-',因为用1代替
            count += i;  // 很巧妙。i只能为0或1,正好代表了+和-的取值。即:count代表的是-的个数,因为+用0代替,累加没有效果
        }
        // 根据异或(两符号相同产生0,不同时产生1)计算得到左下方符号的取值
        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];
        }
        // if((count <= half) || ((t*(t+1)/2-count) <= half))
        backtrack(t + 1); // 按回溯的模板,backtrack是该放到限界函数里的,但这个题目中把限界函数放到了开头,可以改造一下放在这里

        // 反置count
        for (int j = 2; j <= t; j++)
            count -= p[j][t - j + 1];
        count -= i;
    }
}