http://acm.ccucomp.cn/acmhome/problemdetail.do?&method=showdetail&id=1113
1 #include<iostream> 2 #include<algorithm> 3 4 using namespace std; 5 6 int n,sum,len; 7 int count; 8 int sticks[65]; 9 int cmp(const void *a, const void *b) // 比较函数 10 { 11 return *(int *)b - *(int *)a; 12 } 13 14 bool used[65]; 15 16 bool dfs(int pos,int cur, int count) //pos = postion 当前搜到的位置,cur=current 当前搜到的位置的棍子的长度 17 { 18 int flag; // 不能使全局变量,标记 cur是不是为零,以方便下面的剪枝操作 19 if(cur == 0) 20 flag = true; 21 else flag=false; 22 if(count == sum/len) // 如果搜到了len即返回 得到所要结果 23 return true; 24 for(int i = pos; i < n; i++) // 从当前位置遍历 25 { 26 if(used[i]==false)continue; //判断是否被遍历过 27 if(cur + sticks[i] == len) // 如果 相等 则找到一根棍子 28 { 29 used[i] = false; // 标记该段 被用过 30 if(dfs(0,0,count+1))return true; //继续判断其他段是否也能满足 该len 31 used[i] = true; // && 深搜的特征 上一步运行结束,程序得从i 继续重新开始 32 return false; // 该 cur + sticks[i] 不满足此时情况,需要判断cur和其他的sticks的组合 33 } 34 35 else if(cur + sticks[i] < len) // 36 { 37 used[i] = false; // 38 if(dfs(i+1,cur+sticks[i],count)) // 因为当前 cur+sticks[i]< len所以还需要再跟其他的sticks【】组合 39 return true; //判断是否满足情况 40 used[i] = true; // 同上 && 41 if(flag)return false; // 是一剪枝 操作(即当前没有满足情况,就不用再继续循环了) 42 while(sticks[i] == sticks[i+1]) // 亦是剪枝,如果cur+sticks[i] == cur+sticks[i+1],即不用再经过以上的深搜了。 43 i++; 44 } 45 } 46 return false; //遍历的结果没有 就返回false,继续 主函数的循环,len增加1 47 } 48 49 int main() 50 { 51 int i; 52 while(scanf("%d",&n)!=EOF) 53 { 54 if(n == 0) 55 break; 56 sum = 0; 57 int cou = 0; 58 for(i = 0; i < n; i++) 59 { 60 cin>>sticks[i]; //输入每段棍子长度 61 sum += sticks[i]; // 计算总共长度 62 used[i] = true; //初始化 used 深搜dfs时候以此来标记每段棍子 是否合并过 63 } 64 65 qsort(sticks,n,sizeof(sticks[0]),cmp);//是快速排序,如果用sort(sticks,sticks+n,cmp)的话 cmp 为bool型的 66 67 for(len = sticks[0]; len <= sum; len++) // 最长就是sum,即一根棍子 被切了这n段 68 { 69 if(sum%len == 0) //如果有 长度是len,必然能被sum整除,因为是整数条棍子 70 { 71 if(dfs(0,0,0)) // 从零开始深搜 如果搜到 即停止, 得到最小len。 72 break; 73 } 74 } 75 cout<<len<<endl; //输出结果 76 77 78 } 79 return 0; 80 } 81 82 /* 83 测试数据: 84 9 85 5 2 1 5 2 1 5 2 1 86 4 87 1 2 3 4 88 4 89 1 2 5 9 90 9 91 15 3 2 11 4 1 8 8 8 92 64 93 40 40 30 35 35 26 15 40 40 40 40 40 40 40 40 40 40 40 40 40 40 94 40 40 43 42 42 41 10 4 40 40 40 40 40 40 40 40 40 40 40 40 40 95 40 25 39 46 40 10 4 40 40 37 18 17 16 15 40 40 40 40 40 40 40 96 40 97 64 98 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 99 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 100 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 101 1 102 0 103 104 105 106 107 */