符號三角形問題-回溯法

問題描述:算法

  由14個「+」號和14個「-」號組成的符號三角形。this

  2個同號下面是「+」號,2個異號下面是「-」號。spa

如圖:設計

  +   +   _   +   _   +   +code

      +  _   _   _   _   +blog

       _   +  +  +  _get

        _   +   +  _input

         _   +  _io

          _  _class

             +

在通常狀況下,符號三角形第一行有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爲奇數時,也不符合三角形要求。

算法描述:

class Triangle { friend int Compute(int); private: void Backtrack(int t); int half, count, **p long sum; }; void Backtrack(int t) { if((count > half) || (t*(t+1)/2-count>half)) return; if(t>n) sum++; else { for(int i=0;i<2;j++) { 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]; 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; }

算法實例:

#include <stdio.h> #include <conio.h>
#define MAX 100

//global variables
int count=0;//the number of '-'
int sum=0;//the number of the result
int p[MAX][MAX]={0};       //1 is '-' 0 is '+'
int n=0; int half=0;//half=n*(n+1)/4

void back_triangle(int t); int main() { printf("Please input n:"); scanf("%d",&n); half=n*(n+1)/2; if(half%2!=0) { printf("The number that you input is not meaningful for this problem!"); getch(); return 1; } half/=2; back_triangle(1); printf("The result is %d",sum); getch(); return 0; } void back_triangle(int t) { if(count>half || t*(t-1)/2-count>half)//because of this,the "count==half" is not necessary
        return ; if(t>n)   //the count==half is not necessary
 { sum++; for(int temp=1;temp<=n;temp++) { for(int tp=1;tp<=n;tp++) { printf("%d ",p[temp][tp]); } printf("\n"); } printf("\n"); } else { int i; for(i=0;i<2;i++) { p[1][t]=i; count+=i; int j; 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]; } back_triangle(t+1); for(j=2;j<=t;j++) count-=p[j][t-j+1]; count-=i; } } }

運行結果:

相關文章
相關標籤/搜索