hdu 4739 Zhuge Liang's Mines

         今天的网络赛题目,用状态压缩的思想预处理,可以证明出20个点大概不能组成超过100个正方形。于是先预处理所有的正方形,然后0-1背包就可以了。、

 

//#pragma comment(linker, "/STACK:1024000000,1024000000")

#include<algorithm>

#include<iostream>

#include<cstring>

#include<fstream>

#include<sstream>

#include<vector>

#include<string>

#include<cstdio>

#include<bitset>

#include<queue>

#include<stack>

#include<cmath>

#include<map>

#include<set>

#define FF(i, a, b) for(int i=a; i<b; i++)

#define FD(i, a, b) for(int i=a; i>=b; i--)

#define REP(i, n) for(int i=0; i<n; i++)

#define CLR(a, b) memset(a, b, sizeof(a))

#define debug puts("**debug**")

#define LL long long

#define PB push_back

#define MP make_pair

#define eps 1e-10

using namespace std;



const int N = 22;



struct Point

{

    int x, y;

    bool operator < (const Point& rhs) const

    {

        return x < rhs.x || (x == rhs.x && y < rhs.y);

    }

}p[N];



int n, dp[1 << N];

bool vis[1 << N];



vector<int> sqr;



bool ok(int i, int j, int k, int s)

{

    return (p[i].x == p[j].x && p[i].y == p[k].y && p[j].y  == p[s].y && p[s].x == p[k].x) && (p[k].x - p[i].x == p[j].y - p[i].y);

}



void pre()

{

    int i, j, k, s;

    sqr.clear();

    for(i = 0; i < n; i ++)

        for(j = i + 1; j < n; j ++)

            for(k = j + 1; k < n; k ++)

                for(s = k + 1; s < n; s ++)

                    if(ok(i, j, k, s))

                        sqr.PB((1 << i) + (1 << j) + (1 << k) + (1 << s));

}



int main()

{

    //freopen("input.txt", "r", stdin);

    int i, j, ans;

    while(scanf("%d", &n), n > 0)

    {

        for(i = 0; i < n; i ++)

        {

            scanf("%d%d", &p[i].x, &p[i].y);

        }

        sort(p, p + n);

        pre();

        CLR(dp, -1);

        dp[0] = 0, ans = 0;

        for(i = 0; i < sqr.size(); i ++)

        {

            for(j = 0; j < (1 << n); j ++)

            {

                if(((j & sqr[i]) == 0) && dp[j] != -1)

                {

                    dp[j | sqr[i]] = max(dp[j | sqr[i]], dp[j] + 1);

                    ans = max(dp[j + sqr[i]], ans);

                }

            }

        }

        printf("%d\n", ans * 4);

    }

}


 

 

你可能感兴趣的:(HDU)