首先說一下這道題的目的實際就是給出了有限個小木棍的長度,而且所有的棍子都是由有限個長度相同的棍子截斷得到的,讓你求被截棍子的最小長度,本題的算法是深搜,當然需要幾個剪枝的:
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;
}