【算法导论11】回溯法-符号三角形问题

【11回溯法-符号三角形问题】

问题描述:
给定一个数字n,求出符合符号三角形的三角形个数,符号三角形的定义为:
由+ - 符号构成的倒三角形,同号下方为+,异号下方为-,且+号数量=-号数量的三角形。

问题分析:
1 该三角形每行个数依次递减,所以总数是等差数列,S = (1+n)*n/2。
2 三角形的总数S一定为偶数。
3 正负符号的个数一定为S/2。(可行解)
4 每个部分符号三角形一定满足:正或负符号个数<S/2。(剪枝函数)

算法分析
1 首先,分析如果单纯构成全为+的符号三角形如何用递归构成。方法为每次在原来三角形基础上新增一条(斜)边。此过程通过递归解决。
2 然后分析递归传递的参数。由于新增的边符号集合由(该边的第一个符号)第一行的符号决定,因此对第一行的第t个符号进行递归。
3 然后分析剪枝函数,由于存在部分三角形的正负符号>S/2的情况,在此情况下(正号 >half ||负号>half )无需再新增边计算最终三角形,因此需要对该边进行剪枝操作(return),即更换该边对应的第一行符号,重新生成斜边。
4 生成结果。当一次递归进行到第一行的第n个数时(最后一条边),且没有被剪枝,则生成一个符号三角形,sum++。

符号三角形问题算法:

void triangle(int t){//第一行第t个符号
	if(count > half || t(t-2)/2 > half) //half是三角形总数的一半
	return;	
	
	if(t>n){//一轮递归完,生成一个符号三角形且没有被剪枝
	sum++;
	}else{//一轮没有递归完,继续进行新边的递归
		for(i=0;i<2;i++){//第一行第i个符号有两个选择,0或者1,0为+,1为-
			p[1][t] = i;
			count+=i;//count为-号的个数
			
			for(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];
			}
			triangle(t+1);
			
			for(j=2;j<=t;j++)//当回溯到t处后,负号的数量也要回溯。
				count-=p[j][t-j+1];
			}
			count-=i;	
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值