符号三角形(回溯)

符号三角形(回溯)

一、问题描述

图5-4是由14个“+”和14个“-”组成的符号三角形。2个同号下面都是“+”,2个异号下面都是“-”在一般情况下,符号三角形的第一行有n个符号。符号三角形问题要求对于给定的n,计算有多少个不同的符号三角形,使其所含的“+”和、“-”的个数相同。

1 

二、算法分析

1.解向量:x[1:n]表示第一行

2.可行性的约束函数:当前三角形"+"和“-”都不超过n*(n+1)/4

3.无解:n*(n+1)/2为奇数

4.解空间:子集树

void backtrack(int t){
    if(t>n) output(x);
    else
        for(int i=0;i<=1;i++){//只有两个儿子
            x[t]=i;
            if(legal(t)) backtrack(t+1);
        }
}

当确定了三角形的第一行的符号以后,整个三角形就确定了。 

1

①当确定第i个分量时,只有两种取值,1(”+“)和0(”-“)。

1

②确定一个分量三角形深度增加一层,在已有的三角形右边增加了一条边。

x_{i1j}=x_{(i1-1)j}\wedge x_{(i1-1)(j+1)}

③记录”+“的个数:在每次确定符号时用count来记录

5.代码

void  Triangle::backtrack(int t){
    if(count>half||n*(n-1)/4>half) return ;//剪枝
    if(t>n) sum++;//可行解个数+1
    else{
        for(int i=0;i<=1;i++){//两个选择0/1
            p[1][t]=i;//第1行的第t个元素
            count+=i;//记录”+“的个数
            for(int j=2;j<=t;j++){//接下来的2~t行
                p[j][t-j+1]=p[j-1][t-j+1]^p[j-1][t-j+2];
                count+=p[i][t-j+1];//记录”+“
            }
            backtrack(t+1);//进一步深度优先搜索
            for(int j=2;j<=t;j++)//搜索完的还原
                count-=p[i][t-j+1];
            count-=i;
        }
    }

}

6.复杂度:一共n个分量要确定,解空间树一共2^n-1个结点。处理每一个结点的时候,结点的层数为t,则需要对t个元素的值进行计算。

T(n)=O(n2^n)

 

  • 7
    点赞
  • 36
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hnu哈哈

请接受直女的么么哒????

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值