POJ_1011,DFS算法,不可用贪心算法,参考博客
#include<iostream>
#include<algorithm>
using namespace std;
struct Stick{
int m_length; //木棒的长度
bool m_used; //木棒是否被使用过
};
Stick g_stick[70];
int g_total, g_length; //能组成的木棒的组数;组成的木棒的长度
int n, g_sum; //输入的木棍个数;木棍总长度
bool cmp(Stick s1, Stick s2){
return s1.m_length > s2.m_length;
}
/* 已组成的木棒数目;已经组成的长度;搜索的木棒的下标的位置 */
bool Dfs(int c, int len, int pos){
if (c == g_total) return true;
for (int i = pos; i < n; i++){
if (g_stick[i].m_used) continue;
if (len + g_stick[i].m_length == g_length){
g_stick[i].m_used = true;
if (Dfs(c + 1, 0, 0))
return true;
g_stick[i].m_used = false;
return false;
}
else if (g_stick[i].m_length + len < g_length){
g_stick[i].m_used = true;
if (Dfs(c, len + g_stick[i].m_length, i))
return true;
g_stick[i].m_used = false;
//所有方案都不能实现
if (len == 0)
return false;
//快速跳到下一个不同长度的木棒下标
while (g_stick[i].m_length == g_stick[i + 1].m_length)
i++;
}
}
return false;
}
int main(){
while (~scanf("%d", &n) && n){
g_sum = 0;
for (int i = 0; i < n; i++){
scanf("%d", &g_stick[i].m_length);
g_sum += g_stick[i].m_length;
g_stick[i].m_used = false;
}
sort(g_stick, g_stick + n, cmp);
//从木棒的最长的那根开始搜索
bool flag=0;
for (g_length = g_stick[0].m_length; g_length <= g_sum/2+1; g_length++){
if (g_sum%g_length) continue;
g_total = g_sum / g_length;
if (Dfs(0, 0, 0)){
printf("%d\n", g_length);
flag=1;
break;
}
}
if(!flag) printf("%d\n", g_sum);
}
return 0;
}