#include <iostream>
#include <istream>
#include <sstream>
#include <vector>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <cstring>
#include <unordered_map>
#include <unordered_set>
#include <algorithm>
#include <numeric>
#include <chrono>
#include <ctime>
#include <cmath>
#include <cctype>
#include <string>
#include <cstdio>
#include <iomanip>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <functional>
#include <iterator>
using namespace std;
int n, sum, ans, nStart, in;
int lens[64], back[64];
bool IsFind(int cur, int l, int cnt) {
if (cur == 0) {
if (!(--cnt)) return true;
cur = l;
}
if (lens[cur] > 0) {
lens[cur]--;
if (IsFind(0, l, cnt)) return true;
return false;
}
for (int i = cur - 1; i >= 1; i--) {
if (lens[i] > 0) {
lens[i]--;
if (IsFind(cur - i, l, cnt)) return true;
lens[i]++;
}
}
return false;
}
int main()
{
while (cin >> n && n) {
sum = 0, nStart = 0;
memset(lens, 0, sizeof(lens));
for (int i = 0; i < n; i++) {
cin >> in;
//所有棍子总长度
sum += in;
//记录最长的棍子 遍历起点
nStart = max(in, nStart);
//记录长度个数
lens[in]++;
}
ans = sum;
for (int i = nStart; i <= sum; i++) {
//能不能分成 同样长的棍子
if (sum % i != 0)continue;
memmove(back, lens, sizeof(lens));
if (IsFind(i, i, sum / i)) {
ans = i;
break;
}
memmove(lens, back, sizeof(lens));
}
cout << ans << endl;
}
}
截图纪念

本文介绍了一个关于棍子分组的问题求解算法。通过递归搜索的方式寻找将棍子分成相同长度组合的最大可能长度。文章包含完整的C++实现代码,展示了如何利用递归和回溯来解决这一经典问题。
266





