HDU 4277 USACO ORZ

         暴力枚举,然后用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\n", ans);
    }
}

 

 

 

posted on 2013-09-10 19:26  you Richer  阅读(189)  评论(0编辑  收藏  举报