符号三角形问题-回溯法

貌似是子集树问题《符号三角形问题-回溯法》

问题描述:

  由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;
}
    原文作者:回溯法
    原文地址: https://blog.csdn.net/Heated_Youth/article/details/53350276
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞