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

题意:平面上有 n (2 ≤ n ≤ 15) 个点,现用平行于坐标轴的矩形去覆盖所有点,每个矩形至少盖两个点,矩形面积不可为0,求这些矩形的最小面积。

题目链接:http://poj.org/problem?id=2836

——>>因为每个矩形至少要盖两个点,所以,枚举所有的两点组合。。

状态:dp[S] 表示将集合 S 中的所有点覆盖的最小矩形面积

状态转移方程:dp[news] = min(dp[news], dp[S] + r[i].area);

此题为重复覆盖,非精确覆盖,转移时用S ^ r[i].cover是不正确的。。

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>

using std::vector;
using std::min;
using std::max;

const int MAXN = 15;
const int INF = 0x3f3f3f3f;

struct POINT
{
    int x;
    int y;
} p[MAXN + 1];

struct RECTANGLE
{
    int area;
    int cover;
} r[MAXN * MAXN];

int n;
int dp[1 << MAXN];
int area[MAXN + 1][MAXN + 1];
int cnt;

int abs(int x)
{
    return x > 0 ? x : -x;
}

void Read()
{
    for (int i = 0; i < n; ++i)
    {
        scanf("%d%d", &p[i].x, &p[i].y);
    }
}

void Init()
{
    cnt = 0;
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < i; ++j)
        {
            if (j != i)
            {
                int width = abs(p[i].x - p[j].x) == 0 ? 1 : abs(p[i].x - p[j].x);
                int height = abs(p[i].y - p[j].y) == 0 ? 1 : abs(p[i].y - p[j].y);
                r[cnt].area = width * height;
                r[cnt].cover = 0;
                for (int k = 0; k < n; ++k)
                {
                    if (p[k].x >= min(p[i].x, p[j].x) && p[k].x <= max(p[i].x, p[j].x) &&
                            p[k].y >= min(p[i].y, p[j].y) && p[k].y <= max(p[i].y, p[j].y))
                    {
                        r[cnt].cover |= (1 << k);
                    }
                }
                ++cnt;
            }
        }
    }
}

void Dp()
{
    memset(dp, 0x3f, sizeof(dp));
    dp[0] = 0;
    for (int S = 0; S < (1 << n); ++S)
    {
        if (dp[S] != INF)
        {
            for (int i = 0; i < cnt; ++i)
            {
                int news = S | r[i].cover;
                if (news != S)
                {
                    dp[news] = min(dp[news], dp[S] + r[i].area);
                }
            }
        }
    }
    printf("%d\n", dp[(1 << n) - 1]);
}

int main()
{
    while (scanf("%d", &n) == 1 && n)
    {
        Read();
        Init();
        Dp();
    }

    return 0;
}
时间: 2024-10-26 03:01:12

poj - 2836 - Rectangular Covering(状态压缩dp)的相关文章

poj 2836 Rectangular Covering(状态压缩dp)

Description n points are given on the Cartesian plane. Now you have to use some rectangles whose sides are parallel to the axes to cover them. Every point must be covered. And a point can be covered by several rectangles. Each rectangle should cover

poj 2836 Rectangular Covering(状压DP)

Rectangular Covering Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 1716   Accepted: 468 Description n points are given on the Cartesian plane. Now you have to use some rectangles whose sides are parallel to the axes to cover them. Ever

POJ 2836 Rectangular Covering (状压DP)

题意:平面上有 n (2 ≤ n ≤ 15) 个点,现用平行于坐标轴的矩形去覆盖所有点,每个矩形至少盖两个点,矩形面积不可为0,求这些矩形的最小面积. 析:先预处理所有的矩形,然后dp[s] 表示 状态 s 时,最少需要的面积是多少. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #include <string> #include <cstd

POJ 2836 Rectangular Covering 题解 《挑战程序设计竞赛》

POJ 2836 Rectangular Covering铺地板:坐标平面上有n各点,用任意大小(非零)的地板砖覆盖它们,求最省的地板砖总面积.3.4熟练掌握动态规划状态压缩DP先预处理数据,将n个点两两组合形成n * (n-1) / 2个矩形,计算每个矩形的面积和内部点个数.接着利用预处理数据来枚举,定义dp[S] := 矩形集为S时的最省面积先假设平面上没有矩形,那么dp[0]=0,接着一个一个地往平面上加矩形,递推关系是:dp[新矩形集合] = min(dp[新矩形集合], dp[旧矩形集

POJ 3254 Corn Fields 状态压缩DP (C++/Java)

http://poj.org/problem?id=3254 题目大意: 一个农民有n行m列的地方,每个格子用1代表可以种草地,而0不可以.放牛只能在有草地的,但是相邻的草地不能同时放牛, 问总共有多少种方法. 思路: 状态压缩的DP. 可以用二进制数字来表示放牧情况并判断该状态是否满足条件. 这题的限制条件有两个: 1.草地限制. 2.相邻限制. 对于草地限制,因为输入的时候1是可以种草地的. 以"11110"草地分析,就只有最后一个是不可以种草的.取反后得00001  .(为啥取反

POJ 3254 Corn Fields 状态压缩DP

题目链接:http://poj.org/problem?id=3254 思路:状态压缩DP,状态方程为dp[i][j] += (dp[i-1][k]) code: #include <stdio.h> #include <string.h> #define N 500 const int MOD = 100000000; int dp[15][N],ant[N],n,m,k,map[15]; bool ok(int x) { if(x&(x<<1))return

POJ 3691 (AC自动机+状态压缩DP)

题目链接:  http://poj.org/problem?id=3691 题目大意:给定N的致病DNA片段以及一个最终DNA片段.问最终DNA片段最少修改多少个字符,使得不包含任一致病DNA. 解题思路: 首先说一下AC自动机在本题中的作用. ①字典树部分:负责判断当前0~i个字符组成的串是否包含致病DNA,这部分靠字典树上的cnt标记完成. ②匹配部分:主要依赖于匹配和失配转移关系的计算,这部分非常重要,用来构建不同字符间状态压缩的转移关系(代替反人类的位运算). 这也是必须使用AC自动机而

POJ 3254 Corn Fields(状态压缩DP)

Corn Fields Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 4739   Accepted: 2506 Description Farmer John has purchased a lush new rectangular pasture composed of M by N (1 ≤ M ≤ 12; 1 ≤ N ≤ 12) square parcels. He wants to grow some yumm

poj 1185 炮兵阵地(状态压缩dp)

Description 司令部的将军们打算在N*M的网格地图上部署他们的炮兵部队.一个N*M的地图由N行M列组成,地图的每一格可能是山地(用"H" 表示),也可能是平原(用"P"表示),如下图.在每一格平原地形上最多可以布置一支炮兵部队(山地上不能够部署炮兵部队):一支炮兵部队在地图上的攻击范围如图中黑色区域所示: 如果在地图中的灰色所标识的平原上部署一支炮兵部队,则图中的黑色的网格表示它能够攻击到的区域:沿横向左右各两格,沿纵向上下各两格.图上其它白色网格均攻击不