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);

    }

}

 

 

 

你可能感兴趣的:(USACO)