hdu1455
sticks http://acm.hdu.edu.cn/showproblem.php?pid=1455
经典深搜 给你若干根短棒,将其组合成等长的木棒,尽可能短 ,并输出其长度
1 #include <iostream>
2 #include <stdio.h>
3 #include <math.h>
4 #include <algorithm>
5 #include <string.h>
6 using namespace std;
7 int sticks[70],used[70];
8 int flag;
9 int n;
10 int len,piece;
11 int cmp(int a,int b)
12 {
13 return a>b;
14 }
15 //pos表示数组的起始扫描位置,cur表示当前的stick已有长度,cnt表示已有的完整棍子数
16 void DFS(int pos,int cur,int cnt)
17 {
18 if(flag) return;//当前len满足条件
19 if(cur==len)
20 {
21 cnt++;
22 if(cnt==piece)
23 {
24 flag=1;
25 return ;
26 }
27 DFS(0,0,cnt);
28 return ;
29 }
30 if(pos==n) return; //已搜索整个数组
31 int pre=-1;
32 for(int i=pos;i<n;i++)
33 {
34
35 //第i根stick没有用过;之前没有与他等长的stick失效,现有长度加上sticks[i]不大于理论长度
36 if(!used[i]&&pre!=sticks[i]&&cur+sticks[i]<=len)
37 {
38 pre=sticks[i];
39 used[i]=1;
40 DFS(i+1,cur+sticks[i],cnt);
41 used[i]=0;
42 if(flag)//满足条件,返回
43 return ;
44 //最长的一根stick[i]要被废弃,则表示至少有一根最长的要被废弃,不合适
45 if(pos==0)
46 return;
47 }
48 }
49 }
50 int main()
51 {
52 int sum;
53 while(scanf("%d",&n)!=EOF)
54 {
55 if(n==0) break;
56 sum=0;
57 for(int i=0;i<n;i++)
58 {
59 scanf("%d",&sticks[i]);
60 sum+=sticks[i];
61 }
62 sort(sticks,sticks+n,cmp);
63 int max=sticks[0]; //sticks中的最大值,短棍长度必大于此值
64 for(len=max;len<=sum;len++) //len表示短棍的可能长度
65 {
66 if(len>(sum+1)/2)
67 {
68 len=sum;
69 break;
70 }
71 if(sum%len==0)
72 {
73 piece=sum/len; //piece表示len对应的短棍数量
74 memset(used,0,sizeof(used));
75 flag=0;
76 DFS(0,0,0);
77 if(flag)
78 break;
79 }
80 }
81 printf("%d\n",len);
82 }
83 //cout << "Hello world!" << endl;
84 return 0;
85 }