問題描述:
下圖是由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,如果總數為奇數,那麼一定不可能符號...