符号三角形问题

问题描述

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

算法思想

分析:只要第一行的n个符号确定,那么整个木号三角形就确定了,我们可以用x[0:n-1]来表示第一行的n个符号,显然这个问题的解空间是一棵子集树.

  • 解向量存储在x[0:n-1],x[i]==1表示该分量为+,否则为-
  • 约束条件是+与-的个数均不超过n(n+1)/4
  • 限界函数:n(n+1)为奇数时候,不存在N(+)==N(-)的符号三角形

算法实现

#include <iostream>
using namespace std;
const int maxn=100005;
bool x[maxn]={0};
int count=0,half,sum=0,n;
bool** triangle;//三角形
void backTrace(int t)
{
    if(t>n) sum++;
    else{
        for(int i=0;i<2;i++)
        {
            triangle[1][t]=i;       //第一行的符号构造
            count+=i;               
            for(int j=2;j<=t;j++)   //因第一行新增符号,产生一斜边
            {
                triangle[j][t-j+1]=triangle[j-1][t-j+1]^triangle[j-1][t-j+2];
                count+=triangle[j][t-j+1];
            }
            if((count<=half)&&(t*(t+1)/2-count<=half))//限界,+或-的个数都小于等于
                backTrace(t+1);
            //复位
            for(int j=2;j<=t;j++) count-=triangle[j][t-j+1];
            count-=i;
        }
    }
}
bool** structTriangle(int n)
{
    bool **p=new bool* [n+1];
    for(int i=0;i<=n;i++)
        p[i]=new bool [n-i+2];
    return p;
}
int main()
{
    cin>>n;
    half=n*(n+1)/2;
    if(half/2==1) cout<<0<<endl;
    else
    {
        half/=2;
        triangle=structTriangle(n);
        backTrace(1);
        cout<<sum<<endl;
    }
    system("pause");
    return 0;
}

复杂度分析

  • 时间复杂度:计算可行性约束需要O(n)的时间,最坏情况下有O(2^n)个节点需要计算可行性约束,因此时间按复杂度为T(n)=O(n*2^n)
  • 空间复杂度:S(n)=O(n*(n+1)/2)=O(n^2)
原创文章 236 获赞 430 访问量 7万+

猜你喜欢

转载自blog.csdn.net/weixin_44307065/article/details/106048254