符號三角形問題 回溯演算法 java實現

2021-08-19 06:17:43 字數 2116 閱讀 3113

問題描述:

下圖是由14個「+」和14個「-」組成的符號三角形。2個同號下面都是「+」,2個異號下面都是「-」:

符號三角形第一行有n個符號,符號三角形問題要求對於給定的n,計算有多少個不同的符號三角形,使其所含的「+」和「-」的個數相同。

解題思路:

1、不斷改變第一行的每個符號,搜尋符合條件的解,可以使用遞迴回溯。

為了便於運算,設+ 為0,- 為1,這樣可以使用異或運算子表示符號三角形的關係:

++為+即0^0=0, --為+即1^1=0, +-為-即0^1=1, -+為-即1^0=1 

2、因為兩種符號個數相同,可以對題解樹剪枝

當所有符號總數為奇數時無解,當某種符號超過總數一半時無解

演算法設計:

在符號三角形的第一行的前i個符號x[1:i]確定後,就確定了乙個由i*(i+1)/2個符號組成的符號三角形。

下一步確定了x[1:i]的值後,只要在前面確定的符號三角形的右邊加一條邊,就可以擴充套件為x[1:i]所對應的符號三角形。

在回溯法搜尋過程中可用當前符號三角形所包含的「+」號個數與「-」號個數均不超過n*(n-1)/4作為可行性約束,用於剪去不滿足約束條件的子樹。

**:需要的資料:

static int n;//第一行的符號個數

static int half;//n*(n+1)/4

static int count;//當前「+」或者「-」的個數

static int p;//符號三角形矩陣

static long sum;//已找到的符號三角形的個數

初始化及計算:

public static float compute(int nn) 

half = half>>1;

p = new int[n+1][n+1];

backtrack(1);

return sum;

}

回溯演算法1(僅用於計算行數或者列數為n的符號三角形的總數,沒有顯示符號三角形的功能,但是是核心**):

public static void backtrack01(int t) 

if(t>n)

else

backtrack01(t+1);

//恢復現場

for(int j = 2;j<=t;j++)

count -= i;

}} }

回溯演算法2(具備列印符號三角形的功能):

public static void backtrack(int t) 

half = half>>1;

p = new int[n+1][n+1];

backtrack(1);

return sum; }

/*** 演算法1

* @param t

*//* public static void backtrack01(int t)

if(t>n)

else

backtrack01(t+1);

//恢復現場

for(int j = 2;j<=t;j++)

count -= i;

}} }

*/ public static void backtrack(int t) {

if((count>half)||((t*(t-1)/2-count > half)) //對題解樹的剪枝

return;

if(t>n) {

sum++;

//列印符號三角形

for(int i =1;i<=n;i++) {

for(int k = 1;k以行數為4的符號三角形為例,顯示輸出如下:

符號三角形之回溯演算法

下圖是由 14個 和 14個 組成的符號三角形。2個同號下面都是 2個異號下面都是 個符號。符號三角形問題要求對於給定的 n,計算有多少個不同的符號三角形,使其所含的 和 的個數相同。include define max 100 int arr max max int n int sum 2 int...

符號三角形 回溯演算法 C

題目描述 符號三角問題 下圖是由14個 和14個 組成的符號三角形。2個同號下面都是 2個異號下面都是 在一般情況下,符號三角形的第一行有n個符號。符號三角形問題要求對於給定的n,計算有多少個不同的符號三角形,使其所含的 和 的個數相同。參考計算機演算法設計與分析第五版 王曉東 如下 include...

演算法設計 符號三角形(回溯)

給定第一行的符號 只有 數目n,每行比上一行數目少一 形成乙個倒三角 2個相同符號下面為 號,2個不同符號下面為 號,要求有多少種情況使得兩種符號數目相同。第一行為7的符號三角形之一 我們發現 由於只有兩種符號,所以我們可簡化為0 1形式 總符號數為n n 1 2,如果總數為奇數,那麼一定不可能符號...