转载请注明来源 谢谢
#include<iostream>
#include<vector>#include<algorithm>
using namespace std;
const int MAX = 100;
int mark[MAX],stickLength,num;
int sticks[MAX];//这里用数组而不是vector储存棒子的长度
bool dfs(int LastStickCount, int eachLastLen)
{
if (LastStickCount == 0 && eachLastLen == 0)
return true;
if (LastStickCount == 0)
return false;
if (eachLastLen == 0)
eachLastLen = stickLength;
for (int i = 0; i < num; i++)
{
if (sticks[i]>eachLastLen || mark[i] != 0)
continue;
if (i > 0 && mark[i - 1] == 0 && sticks[i] == sticks[i - 1])//剪枝1:在某一位置某一长度尝试失败,那么与它相同长度的棒子在同一位置就没必要尝试了,结果一定失败
continue;
mark[i] = 1;
if (dfs(LastStickCount - 1, eachLastLen - sticks[i]))
return true;
mark[i] = 0;
if (eachLastLen == stickLength || sticks[i] == eachLastLen)//剪枝2:如果尝试的位置是棍的最初位置,那么这个位置尝试失败一定是棍子的长度有问题,因为如果这个 位置最长的棒子尝试失败,那这根棒子必将出现在下面的棍子的最初位置,肯定也是尝试失败,
return false; 因此失败的话就直接换棍子的长度。
//如果尝试的位置是棍的最后位置,如果这个位置尝试成功,但是下面的棍子组合却出现失败,
那肯定也是因为棍的长度有问题,因为如果将最后一根棒子用更短的几根棒子替代的话,
这根被替代的棒子肯定会出现在下面那些棍子的组合中,结局肯定也是失败。
再细化说,这根被代替的棒子肯定会出现在下面某根棍子中,
如果下面这根棍子组装成功的话,那当初用那几根小棒子也肯定能组装成功
}
return false;
}
bool compare(int a, int b)
{
return a > b;
};
int main()
{
while (cin >> num&&num != 0)
{
int totalLength = 0;
for (int i = 0; i < num; i++)
{
cin >> sticks[i];
mark[i] = 0;
totalLength += sticks[i];
}
sort(sticks, sticks+num, compare);
for (stickLength = sticks[0]; stickLength <= totalLength; stickLength++)
{
if (totalLength%stickLength != 0)//剪枝3:如果不是因数就没必要进行尝试了,因为木棍要等长,那肯定要能整除总长度
continue;
if (dfs(num, stickLength))
{
cout << stickLength << endl;
break;
}
}
}
return 0;
}