首先说一下这道题的目的实际就是给出了有限个小木棍的长度,而且所有的棍子都是由有限个长度相同的棍子截断得到的,让你求被截棍子的最小长度,本题的算法是深搜,当然需要几个剪枝的:
1、截棍子的最小长度>=小木棍的最大长度;
2、截棍子的长度一定是总长度的分子;
3、搜索时第i-1条木条跟第i(i>0)木条长度相等且没有被使用,即第i根木棍也不会用;
4、第一根未使用木条放进去都不能为true,即该长度不对
//
// main.cpp
// T1011
//
// Created by 小哲 on 16/10/3.
// Copyright © 2016年 小哲. All rights reserved.
//
#include <iostream>
using namespace std;
int length;
bool *IsUsed;
int numArray[64];
bool DFS(int num,int left,int l)
{
if (num==0&&left==0) {
return true;
}
if (left==0) {
num--;
left=l;
}
for (int i=0; i<length; i++) {
if (!IsUsed[i]&&numArray[i]<=left) {
if (i>0&&numArray[i-1]==numArray[i]&&!IsUsed[i-1]) {
continue;//在i-1条木条跟当前i木条长度相等且没有被使用,即当前这根也不会用
}
IsUsed[i]=true;
if (DFS(num, left-numArray[i], l)) {
return true;
}
IsUsed[i]=false;
if (left==l||numArray[i]==left) {//left==l说明连第一根木条放进去都不行,即为错;numArray[i]==left说明最大的这根放进去不行,那比他小的凑出left长度的放进去也不能成功
return false;
}
}
}
return false;
}
void sort(int n)
{
for (int i=0; i<n; i++) {
for (int j=n-1; j>=i; j--) {
if (numArray[i]<numArray[j]) {
int temp=numArray[i];
numArray[i]=numArray[j];
numArray[j]=temp;
}
}
}
}
int main(int argc, const char * argv[]) {
int tempNum;
cin>>length;
while (length!=0) {
IsUsed=new bool[length];
int sum=0;
for (int i=0; i<length; i++) {
cin>>tempNum;
sum+=tempNum;
numArray[i]=tempNum;
}
sort(length);//先从大到小排序
for (int i=numArray[0]; i<=sum; i++) {
if (sum%i==0) {
for (int j=0; j<length; j++) {
IsUsed[j]=false;
}
if (DFS(sum/i-1, i, i)) {
cout<<i<<endl;
break;
}
}
}
cin>>length;
}
return 0;
}