poj 2836 Rectangular Covering (状态压缩dp~)

来源:互联网 发布:微信营销数据分析 编辑:程序博客网 时间:2024/05/21 15:00

刚看到题目时真没想到是状态压缩,当然我什么想法也没有,果然是我太菜了。。。。后来看了题解还是觉挺清楚的。。。

有个坑!!!

算面积那里,注意矩形边长万一小于1,是需要取整为1的。不然会WA。

#include <stdio.h>#include <string.h>#include <cmath>#include <iostream>#include <vector>using namespace std;#define MAX_N 20#define INF 0x3f3f3fint x[MAX_N], y[MAX_N];struct Rectangle {    int cover;  //点集    int area;   //面积    Rectangle(int c, int a) {        cover = c;        area = a;    }    //第几位表示第几个点    void addpoint(int c) { cover |= (1 << c); }};//点k在不在i和j组成的矩形中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 dp[1 << 16];int main(void) {    int n;    while (scanf("%d", &n) == 1 && n) {        int xx, yy;        for (int i = 0; i < n; i++) {            scanf("%d%d", &xx, &yy);            x[i] = xx;            y[i] = yy;        }        vector<Rectangle> V;        //对每个矩形进行初始化        for (int i = 0; i < n; i++) {            for (int j = i + 1; j < n; j++) {                Rectangle r((1 << i) | (1 << j),                            max((int)abs(x[i] - x[j]), 1) *                                max(((int)abs(y[i] - y[j])), 1));                for (int k = 0; k < n; k++) {                    if (is_in(i, j, k)) r.addpoint(k);                }                V.push_back(r);            }        }        // dp[i]的含义是包含i个矩形的最小面积        memset(dp, INF, sizeof(dp));        dp[0] = 0;        for (size_t i = 0; i < V.size(); i++) {            for (int state = 0; state < (1 << n); state++) {                int newstate = state | V[i].cover;                //此条件限制了只能从第0个开始dp                if (dp[state] == INF) continue;                if (newstate == state) continue;                dp[newstate] = min(dp[newstate], dp[state] + V[i].area);            }        }        printf("%d\n", dp[(1 << n) - 1]);    }    return 0;}