暂时只想到两处可以剪枝的地方。 #include <iostream> #include <stdio.h> #include <cstring> #include <algorithm> using namespace std; const int MAXN = 64; int stick[MAXN]; bool flag[MAXN]; int n; int sum; int len; int cnt; bool cmp(int a, int b) { return a > b; } bool dfs(int l, int start, int num) { if(l == len) { start = 0; num ++; l = 0; } if(num == cnt) return true; for(int i=start; i<n; i++) { //剪枝 1:对某一长度的搜索肯定是一直向右搜,如果stick[i]和stick[i-1]相等 //且 stick[i-1]没有被分配,则stick[i-1]一定是分配失败了, //所以stitch[i]就不用再考虑 if(i && !flag[i-1] && stick[i] == stick[i-1]) continue; if(!flag[i] && l+stick[i]<=len) { flag[i] = true; if(dfs(l+stick[i], i+1, num)) return true; flag[i] = false; //剪枝 2:在剩下的木棒中找新的组合,如果第一根无法满足, //则总体就不会满足,因为这第一根木棒是一定要被分配的 if(l == 0) break; } } return false; } int main() { while(1) { scanf("%d", &n); if(!n) break; sum = 0; for(int i=0; i<n; i++) { scanf("%d", stick+i); sum += stick[i]; } sort(stick, stick+n, cmp); for(int i=stick[0]; ; i++) { if(sum % i) continue; len = i; cnt = sum / i; memset(flag, 0, sizeof(flag)); if(dfs(0, 0, 1)) { printf("%d/n", i); break; } } } return 0; }