貌似是子集树问题
问题描述:
由14个“+”号和14个“-”号组成的符号三角形。
2个同号下面是“+”号,2个异号下面是“-”号。
在一般情况下,符号三角形第一行有N个符号,该问题要求对于给定n计算有多少种不同的符号三角形。使其所含的+ — 个数相同。
算法设计:
1 x[i] =1 时,符号三角形的第一行的第i个符号为+
2 x[i] =0时,表示符号三角形的第一行的第i个符号位-
共有i(i+1)/2个符号组成的符号三角形。
3 确定x[i+1]的值后,只要在前面确定的符号三角形的右边加一条边就扩展为x[1:i+1]所相应的符号三角形。
4 最后三角形中包含的“+”“-”的个数都为i(i+1)/4,因此搜索时,个数不能超过…若超直接可以剪去分枝。
5 当给定的n(n+1)/2为奇数时,也不符合三角形要求。
输入:
第一行符号的个数
输出:
#include <iostream>
using namespace std;
class Triangle
{
friend int Compute(int);
private:
void Backtrack(int t);
int n, // 第一行的符号个数
half, // n*(n+1)/4;
count, //当前"+"号个数
**p; //符号三角形矩阵
long sum;
};
void Triangle::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;
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;
}
}
int Compute(int n)
{
Triangle X;
X.n=n;
X.count=0;
X.sum=0;
X.half=n*(n+1)/2;
if(X.half%2==1)return 0; //符号总个数为奇数时,无解
X.half=X.half/2;
int **p=new int *[n+1];
for(int i=0; i<=n; i++) //定义了用于存储符号三角形的 二维数组
p[i]=new int[n+1]; //"+"号用"1", "-"号用"0";
for(int i=0; i<=n; i++)
for(int j=0; j<=n; j++)
p[i][j]=0;
X.p=p;
X.Backtrack(1);
return X.sum;
}
int main()
{
int n,ans;
cout<<"输入第一行符号的个数( 需要满足n*(n+1)/2是偶数 )"<<endl;
while(cin>>n)
{
ans=Compute(n);
cout<<ans<<endl;
}
return 0;
}