HDU 1455(Sticks) POJ 1011(Sticks)
/*DFS好题
Date: 2012/10/14
题目链接地址:http://poj.org/problem?id=1011
http://acm.hdu.edu.cn/showproblem.php?pid=1455
思路:首先可以确定的是,木棍初始值的长度肯定是所有木棍段之和(假设为sum)的约数,木棍初始值的最小值
为给定木棍段的最大值(假设为max),木棍初始值的最大值为所有木棍段之和。所以从max到sum之间依次
判断是sum约数的长度是否满足题目要求即可
先给木棍段从大到小排序,这对以后的剪枝有帮助
剪枝1:在刚开始组成一个初始木棍的时候,如果某木棍段的长度小于初始木棍的长度且不满足的话,则返回
剪枝2:如果一个木棍段的长度和木棍初始值相等,且不满足的话,则返回
剪枝3:如果木棍段的值不满足的话,那么和当前木棍段相等的木棍段也不满足
*/
#include<iostream> #include<algorithm> using namespace std; #define maxn 65 int n,sum,arr[maxn]; bool flag,visited[maxn]; bool cmp(int a,int b) { return a > b; } void dfs(int k,int i,int s,int num)//k表示初始值,i表示当前值的下标,s表示当前木棍长度的和,num表示已用的木棍段的数量 { if(num == n && s == k) { flag = 1; return; } if(flag) return; s = s%k,visited[i] = true; for(int j = 1; j <= n; j++) { if(!visited[j] && s+arr[j] <= k) { dfs(k,j,s+arr[j],num+1); if(s == 0 && arr[j] < k) break;//刚开始如果当前值小于初始值且不满足的话,那么这个初始值是不合法的 if(arr[j] == k) break; //当前值等于初始值不行的话,那这个初始值就是不合法的 while(arr[j] == arr[j+1]) j++; //当前值不行,那与当前值相等的也不满足 } } visited[i] = false; } int main() { //freopen("1010.txt","r",stdin); while(scanf("%d",&n) && n) { int i; sum = flag = 0; for(i = 1; i <= n; i++) { scanf("%d",&arr[i]); sum += arr[i]; } sort(arr+1,arr+n+1,cmp); for(i = arr[1]; i <= sum; i++) { if(i == sum) { printf("%d\n",sum); break; } if(sum%i == 0) dfs(i,1,arr[1],1); if(flag) { printf("%d\n",i); break; } } } return 0; }

浙公网安备 33010602011771号