//============================================================================
// Name : 1011.cpp
// Author :
// Version :
// Copyright : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================
#include <stdio.h>
#include <algorithm>
#include <cstring>
using namespace std;
#define MAX_M 51
int n;
int sum;
int len;
int max_data;
int number[MAX_M];
bool cmp(const int &a, const int &b) {
return a > b;
}
/**
* rest 要拼接的剩余的长度
* sticks 剩余的要拼接的棒数
* current 当前使用的第一棒的长度
* next 下一棒的长度
*/
int dfs(int rest, int sticks, int current, int next) {
int i;
if (rest == 0) {
sticks--;
//拼接成功
if (sticks == 0)
return 1;
for (i = current; number[i] == 0; i--)
; //选择下一个木棒的长度
number[i]--;
if (dfs(len - i, sticks, i, i))
return 1;
number[i]++;
} else {
for (i = min(next, rest); i > 0; i--) {
if (number[i] > 0) {
number[i]--;
if (dfs(rest - i, sticks, current, i))
return 1;
number[i]++;
if (rest == i)
return 0;
}
}
}
return 0;
}
int result() {
for (int i = max_data; i <= sum / 2; i++) {
if (sum % i == 0) {
len = i;
int finalcomplete = sum / i;
number[max_data]--;
if (dfs(len - max_data, finalcomplete, max_data, max_data))
return i;
number[max_data]++;
}
}
return sum;
}
int main() {
while (true) {
scanf("%d", &n);
if (n == 0)
break;
sum = 0;
max_data = 0;
memset(number, 0, MAX_M * sizeof(int));
for (int i = 0; i < n; i++) {
int l;
scanf("%d", &l);
max_data = max(max_data, l);
number[l]++;
sum += l;
}
int out = result();
printf("%d\n", out);
}
return 0;
}
poj1011
最新推荐文章于 2020-12-22 11:36:28 发布