题意:最多十五根木条,凑成一个三角形,每根木条都用上,问有多少种类型的三角形(至少一条边不等)。
dfs暴搜+剪枝,用set去重
#include <iostream>
#include <cstdio>
#include <set>
#include <cstring>
using namespace std;
int N, len[20], total, ans;
set< pair<int, int> > myset;
void sortABC(int& a, int& b, int& c) {
int tmp;
if (a > b) tmp = a, a = b, b = tmp;
if (a > c) tmp = a, a = c, c = tmp;
if (b > c) tmp = b, b = c, c = tmp;
}
void dfs(int deep, int a, int b, int c) {
if (a >= total - a || b >= total - b || c >= total - c)
return;
if (deep == N) {
sortABC(a, b, c);
if (a + b <= c) return;
if (myset.find(make_pair(a, b)) != myset.end())
return;
myset.insert(make_pair(a, b));
ans++;
return;
}
dfs(deep+1, a+len[deep], b, c);
dfs(deep+1, a, b+len[deep], c);
dfs(deep+1, a, b, c+len[deep]);
}
int main()
{
int T;
scanf ("%d", &T);
while (T--) {
scanf ("%d", &N);
total = 0;
for (int i = 0; i < N; i++) {
scanf ("%d", &len[i]);
total += len[i];
}
myset.clear();
ans = 0;
dfs(1, len[0], 0, 0);
printf ("%d\n", ans);
}
return 0;
}