符号三角形问题

问题描述:

如下图是由14个“+”和14个“-”组成的符号三角形, 2个同号下面都是“+”,2个异号下面都是“-”。
1 - + + - + + +
2 - + - - + +
3 - - + - +
4 + - - -
5 - + +
6 - +
7 -
在一般情况下,符号三角形的第一行有n个符号, 符号三角形问题要求对于给定的n, 计算有多少个不同的符号三角形,使其所含的“+”和“-”的个数相同。 这是在书本中回溯里的一道题目,回溯约等于深度优先搜索

回溯的大概:如果一种情况可能,继续往下递归直到边界;如果超出了限定条件就剪枝,所以能一直递归到边界的一定是未被剪枝也就是符合条件的情况,即答案。

在这道题当中,可以得到限制:== “+”,“-”数量相等,总数量为偶数。==
并且当三角形的第一行确定后,整个三角形也可以确定。所以方法就是尝试第一行的内容,通过剪枝、递归得到答案。

在这里插入图片描述
晕了,这图片咋这么大

上图就是它递归的大概,每次新加一个点,都会斜着新加一排。
注意! 每次新加的点都要分为两种情况:+ 和 -;

下面是代码:

#include<cstdio>
using namespace std;
int n;
int half;
int sum; 
int count; //1代表+ ; 0代表- ; count就是+的计数 
int p[100][100];

void Dfs(int t);

int main()
{
	scanf("%d",&n);
	if((n+1) * n % 4)
	{
		printf("ERROR");
		return 0 ;
	} 
	half = (n+1) * n / 4; // + 和 - 都不能超过half
	sum = 0; //答案数初始化;
	count = 0; 
	
	Dfs(0);
	
	printf("%d",sum); 
	
	return 0;
}

void Dfs(int t)//第t步,也就是第一行的第t位 
{
		if(t == n && count == half)
		{
			sum ++;
			return ; //得到一个答案,向上return 回溯 
		} 
		
		//如果还有位子,一个位子要尝试 + - 两种情况 
		for(int i = 0; i < 2; i++) 
		{
			p[0][t] = i;
			count += i; 
			
			for(int j = 1; j <= t; j++)
			{
				p[j][t-j] = p[j-1][t-j]^p[j-1][t-j+1];
				count += p[j][t-j];
			}
			
			if(count <= half && (t+2)*(t+1)/2 - count <= half)//当前图形中+ -都没超过一半
			{
				Dfs(t + 1); 
			} 
			
			//还原本次,考虑下一个符号
			for( int j = 1; j <= t; j++)
			{
				count -= p[j][t-j];
			} 
			count -= i;
		}
}	
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值