HDOJ 4277 USACO ORZ(set判重+dfs)

来源:互联网 发布:松江报警主机编程号 编辑:程序博客网 时间:2024/06/06 03:40
//判重 + 剪枝,状态压缩做会超时,需要做一些优化#include <cstdio>#include <cmath>#include <set>using namespace std;const int nMax = 17;int N;int A[nMax];int SUM;void swap(__int64 &a, __int64 &b){__int64 temp = a;a = b;b = temp;}set<__int64> _set;set<__int64>::iterator it;__int64 ans;void dfs(__int64 a, __int64 b, __int64 c, int cur, __int64 sum){if(cur >= N){if(a > b) swap(a, b);if(a > c) swap(a, c);if(b > c) swap(b, c);if(a + b > c){__int64 h = (__int64)a * SUM * SUM+ b * SUM + c;if(_set.find(h) == _set.end()){_set.insert(h);ans ++;}}return;}sum -= A[cur];if(a + A[cur] < b + c + sum && a + A[cur] <= b + sum) dfs(a + A[cur], b, c, cur + 1, sum);//a < b < cif(b + A[cur] < a + c + sum && b + A[cur] <= c + sum) dfs(a, b + A[cur], c, cur + 1, sum);if(c + A[cur] < a + b + sum) dfs(a, b, c + A[cur], cur + 1, sum);}int main(){int T;scanf("%d", &T);while(T --){_set.clear();scanf("%d", &N);int i, j;SUM = 0;for(i = 0; i < N; ++ i) scanf("%d", &A[i]), SUM += A[i];ans = 0;dfs(0, 0, 0, 0, SUM);printf("%I64d\n", ans);}return 0;}