暴力枚举,然后用set判重,只是时间复杂度有点儿高。。。
#include<algorithm> #include<iostream> #include<cstring> #include<vector> #include<cstdio> #include<cmath> #include<set> #define SL strlen #define PBpush_back #define LL long long #define INF 0X3f3f3f3f #define CLR(a, b) memset(a, b, sizeof(a)) using namespace std; const int N = 17; structtriangular { int a, b, c; bool operator < (const triangular& rhs) const { if(a != rhs.a) return a < rhs.a; if(b != rhs.b) return b < rhs.b; return c < rhs.c; } } tri; set<triangular>hav; int a[N], dp[1 << N]; bool ok(int a, int b, int c) { if(a + b > c && abs(a - b) < c) return 1; return 0; } int check(int k) { int i = 0, ret = 0; while(k) { if(k & 1) ret += a[i]; k >>= 1;i ++; } return ret; } int main() { //freopen("input.txt", "r", stdin); int n, t, i, j, k, s, ans; scanf("%d", &t); while(t --) { scanf("%d", &n); for(i = 0; i < n; i ++) { scanf("%d", &a[i]); } for(i = 1; i < (1 << n); i ++) { dp[i] = check(i); } ans = 0; hav.clear(); for(i = 1; i < (1 << n); i ++) { k = (1 << n) - i - 1; for(j = (k - 1) & k; j; j = k & (j - 1)) { if(dp[j] >= dp[i]) { s = (1 << n) - 1 - i - j; if(dp[s] >= dp[j] && ok(dp[i], dp[j], dp[s])) { tri.a = dp[i], tri.b = dp[j], tri.c = dp[s]; if(!hav.count(tri)) { ans ++; hav.insert(tri); } } } } } printf("%d ", ans); } }