一年前就有学长推荐了,拖到昨天才做。
很喜欢这种题,简洁易懂,直截了当。
经典的dfs,难度适中。
不过对我来说还是有点障碍,首先是不敢写递归,其次要想到剪枝。
#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;
int a[70], n;
bool v[70];
bool cmp(int x, int y){
return x > y;
}
int dfs(int len, int rem, int left){
if(!left && !rem) return len; //全部匹配完毕
if(!rem) rem = len; //匹配下一根
for(int i = 0; i < n; i++) if(!v[i]){
if(a[i] <= rem){
v[i] = 1;
if(dfs(len, rem - a[i], left - 1)) return len;
v[i] = 0; //不用这根
if(rem == a[i] || rem == len) break; //这里的剪枝很关键
while(a[i] == a[i + 1]) i++; //寻找下一个长度的木棒
}
}
return 0;
}
int main(){
while(cin >> n && n){
int sum = 0;
for(int i = 0; i < n; i++){
cin >> a[i];
sum += a[i];
}
sort(a, a + n, cmp);
for(int len = a[0]; len <= sum; len++) if(sum % len == 0){ //枚举木棒长度
memset(v, 0, sizeof(v));
int res = dfs(len, len, n);
if(res){
cout << res << endl;
break;
}
}
}
return 0;
}