您的位置:首页 > Web前端 > AngularJS

Poj 2836 Rectangular Covering(状压DP)

2015-08-06 18:50 627 查看
题意:

给你n个顶点,用任意个边垂直于x轴和y轴的矩形进行覆盖,最小覆盖面积是多少,都为整数.

思路:

先预处理处两两点的面积,和这个面积包围的点。

之后进行这样的定义 dp[S] := 当前点集为S时的最小面积

若将要选取的两个点点集为coverd, 面积为area



dp[S | ( 1 << coverd) ] = dp[S] + area ; {coverd | coverd 不属于 点集 S}

制约:

(2 ≤ n ≤ 15).

(−1,000 ≤x,
y ≤ 1,000)


/***********************************************
 * Author: fisty
 * Created Time: 2015-08-04 22:23:06
 * File Name   : poj2836.cpp
 *********************************************** */
#include <iostream>
#include <cstring>
#include <deque>
#include <cmath>
#include <queue>
#include <stack>
#include <list>
#include <map>
#include <set>
#include <string>
#include <vector>
#include <cstdio>
#include <bitset>
#include <algorithm>
using namespace std;
#define Debug(x) cout << #x << " " << x <<endl
#define Memset(x, a) memset(x, a, sizeof(x))
const int INF = 0x3f3f3f3f;
typedef long long LL;
typedef pair<int, int> P;
#define FOR(i, a, b) for(int i = a;i < b; i++)
#define lson l, m, k<<1
#define rson m+1, r, k<<1|1
#define MAX_N 16
int n;
int dp[1<<MAX_N];
int x[MAX_N], y[MAX_N];
struct Rect{
    int coverd;
    int area;
    Rect(const int& coverd, const int& area) : coverd(coverd), area(area){}

    void add(int i){
        coverd |= 1 << i;
    }
};
bool is_in(int i, int j, int k){
    return ((x[i] - x[k]) * (x[j] - x[k]) <= 0) && ((y[i] - y[k]) * (y[j] - y[k]) <= 0);
}
int main() {
    //freopen("in.cpp", "r", stdin);
    //cin.tie(0);
    //ios::sync_with_stdio(false);
    while(scanf("%d", &n) && n){
        for(int i = 0;i < n; i++){
            scanf("%d %d", &x[i], &y[i]);
        }
        vector<Rect> Rectangle;
        for(int i = 0;i < n; i++){
            for(int j = i+1;j < n; j++){
                Rect r((1<<i )| (1<<j), max(1, (int const &) abs(x[i] - x[j])) * max(1, (int const &) abs(y[i] - y[j])));
                if(i != j){
                    for(int k = 0;k < n; k++){
                        if(is_in(i, j, k)){
                            r.add(k);
                        }
                    }
                }
                Rectangle.push_back(r);
            }
        }
        Memset(dp, 0x3f);
        dp[0] = 0;
        vector<Rect>::iterator it;
        for(it = Rectangle.begin();it != Rectangle.end(); it++){
            for(int s = 0;s < (1<<n); s++){
                int ns = s | it -> coverd;
                if(ns != s && dp[s] != INF){
                    dp[ns] = min(dp[ns], dp[s] + it -> area);
                }
            }
        }
        printf("%d\n", dp[(1<<n)-1]);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: