题意:将n跟木棒分成3堆,3堆木棒的总和分别为a,b,c,满足能以a,b,c组成三角形,问有多少种不同的情况
思路:DFS+剪枝 先固定一根木棒在某一堆(第一根放在a b c 都是等效)所以预处理第一根
将木棒由大到小排序 优化时间;
#include <cstdio>
#include <iostream>
#include<algorithm>
#include<set>
using namespace std;
pair<int, int>k;
set<pair<int,int>>s;
int n,ans,sum;
int x[20];
bool cmp(int a, int b)
{
return a>b;
}
int find(int a, int b, int c)
{
if (a > b) { int t = a; a = b; b = t; }
if (b > c) { int t = b; b = c; c = t; }
if (a > b) { int t = a; a = b; b = t; }
if (a + b > c)
{
k = make_pair(a, b);
if (s.count(k) == 0) { s.insert(k); return 1;}
}
return 0;
}
void DFS(int a, int b ,int c ,int i)
{
if (a > sum / 2 || b > sum / 2 || c > sum/2 ) return ;
if (i == n) { ans += find(a, b,c); }
else
{
DFS(a + x[i + 1], b, c, i + 1);
DFS(a, b + x[i + 1], c, i + 1);
DFS(a, b, c + x[i+1] , i + 1);
}
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
sum = 0;
for (int i = 1; i <= n; i++)
{
scanf("%d", &x[i]);
sum += x[i];
}
sort(x + 1,x+1+n,cmp);
ans = 0;
if(n>=3) DFS(x[1],0,0,1);
printf("%d\n", ans);
s.clear();
}
return 0;
}