http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=204
非递归版本,回赎+剪枝
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
const int MAX = 30;
enum Operation
{
Nop,
Append,
IncreaseLast,
BackTracking
};
class Equation
{
public:
vector<int> numbers;
bool operator < (const Equation& other) const
{
if (numbers.size() < other.numbers.size())
return true;
else if (numbers.size() > other.numbers.size())
return false;
else
{
for (int i = 0; i < numbers.size(); i++)
if (numbers[i] < other.numbers[i])
return true;
else if (numbers[i] > other.numbers[i])
return false;
}
}
int GetSum()
{
int sum = 0;
for (int i = 0; i < numbers.size(); i++)
sum += numbers[i];
return sum;
}
};
vector<Equation> v;
bool FindAdditiveEquation(int a[MAX], int n, int targetNum, int targetSum)
{
int index[MAX] = {0};
int num = 1;
int sum = a[index[num - 1]];
bool find = false;
while (true)
{
Operation op = Nop;
if (num == targetNum)
{
if (sum < targetSum)
{
if (index[num - 1] == n - 1) // remove last one, increase the last second one
op = BackTracking;
else // just increase the last one
op = IncreaseLast;
}
else if (sum == targetSum)
{
find = true;
Equation equ;
for (int i = 0; i < num; i++)
equ.numbers.push_back(a[index[i]]);
v.push_back(equ);
op = BackTracking;
}
else
{
op = BackTracking;
}
}
else
{
if (sum < targetSum) // can append
{
if (index[num - 1] == n - 1) // the last one
{
if (num == 1)
return find;
else
op = BackTracking;
}
else
op = Append;
}
else
{
if (num == 1)
return find;
else
op = BackTracking;
}
}
if (op == Append)
{
index[num] = index[num - 1] + 1;
num++;
sum += a[index[num - 1]];
}
else if (op == IncreaseLast)
{
sum -= a[index[num - 1]];
index[num - 1]++;
sum += a[index[num - 1]];
}
else if (op == BackTracking)
{
sum -= a[index[num - 1]]; // remove the last one
num--;
sum -= a[index[num - 1]];
index[num - 1]++; // increase
sum += a[index[num - 1]];
}
}
}
int main()
{
int n;
int m;
int a[MAX];
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> m;
for (int j = 0; j < m; j++)
cin >> a[j];
sort(a, a + m);
bool find = false;
v.clear();
for (int j = 2; j <= m - 1; j++)
for (int k = j; k < m; k++)
if (FindAdditiveEquation(a, k, j, a[k]))
find = true;
if (find)
{
sort(v.begin(), v.end());
for (int j = 0; j < v.size(); j++)
{
for (int k = 0; k < v[j].numbers.size(); k++)
{
if (k == 0)
cout << v[j].numbers[k];
else
cout << "+" << v[j].numbers[k];
}
cout << "=" << v[j].GetSum() << endl;
}
}
else
cout << "Can't find any equations." << endl;
cout << endl;
}
}