| ||||||||||
| Online Judge | Problem Set | Authors | Online Contests | User | ||||||
|---|---|---|---|---|---|---|---|---|---|---|
| Web Board Home Page F.A.Qs Statistical Charts | Current Contest Past Contests Scheduled Contests Award Contest | |||||||||
参考了网上的思路,总算A了,此题真是回溯的神题啊!#include <iostream>
#include <algorithm>
using namespace std;
class Sticks
{
protected:
int* a;
int n;
int sum;
bool* used;
bool DFS(int stickCount, int len, int index, int aim);
public:
Sticks(int n);
~Sticks();
void ReadData();
int DFS();
};
Sticks::Sticks(int n)
{
this->n = n;
a = new int[n];
used = new bool[n];
}
Sticks::~Sticks()
{
delete[] a;
delete[] used;
}
void Sticks::ReadData()
{
sum = 0;
for (int i = 0; i < n; i++)
{
cin >> a[i];
sum += a[i];
}
}
// stickCount:下标index(含)前已经搜索过的组合成完整的长度为aim的长棍子的数量
// len:本次搜索已经构成的长度
// index:要搜索下标index(不含)之后的短棍子
// aim:目标长度
bool Sticks::DFS(int stickCount, int len, int index, int aim)
{
if (stickCount == sum / aim)
{
return true;
}
for (int i = index + 1; i < n; i++)
{
if (used[i])
{
continue;
}
if (len + a[i] == aim)
{
used[i] = true;
if (DFS(stickCount + 1, 0, -1, aim))
{
return true; //这里的程序结构很巧妙
}
used[i] = false;
return false;
}
else if (len + a[i] < aim)
{
used[i] = true;
if (DFS(stickCount, len + a[i], i, aim))
{
return true;
}
used[i] = false;
if (len == 0)
{
return false;
}
while (a[i] == a[i + 1]) // 剪枝技巧之一
{
i++;
}
}
}
return false;
}
int Sticks::DFS()
{
sort(a, a + n);
reverse(a, a + n);
for (int aim = a[0]; aim <= sum; aim++)
{
if (sum % aim == 0)
{
memset(used, false, sizeof(bool) * n);
if (DFS(0, 0, -1, aim))
{
return aim;
}
}
}
return 0;
}
int main()
{
int n = 0;
cin >> n;
while (n > 0)
{
Sticks obj(n);
obj.ReadData();
cout << obj.DFS() << "\n";
cin >> n;
}
return 0;
}
Followed by:
Post your reply here: |
All Rights Reserved 2003-2013 Ying Fuchen,Xu Pengcheng,Xie Di
Any problem, Please Contact Administrator