POJ 2836 Rectangular Covering 状态压缩DP(铺砖问题)

一、题目大意

坐标系中有n个点,它们满足 -1000<=x<=1000,-1000<=y<=1000。

现在要在坐标系中放一些矩形,要使得每个点都被矩形覆盖(被矩形的边或者顶点覆盖也可以),每个矩形都必须满足面积大于0,且每个矩形最少要覆盖两个点。

请你输出覆盖所有点时,如何使所有矩形的面积和最小,输出这个面积和。

二、解题思路

我们可以从左上角的点开始,一点点的覆盖到右下角的点。

那么对于第 i 个点,我们可以认为

1、i 以前的点都被覆盖;

2、如果 i 还未被覆盖,则它必须被覆盖。

同时思考下,当铺设到第 i 个点时,对于覆盖情况固定时,铺完剩下的点需要的最小矩形面积是固定的。

则可以定义DP数组,DP[S][i]代表已经铺设的点的集合为S时,铺设好第 i 个点到最后一个点所需要的最小的矩形面积。

对于最后一个点n-1,如果S包含n-1,则DP[S][n-1]=0,如果不包含,那么DP[S][n-1]=点n-1到其余点的矩形的面积的最小值。

那么借助这个思路,我们就可以展开循环,外层放 i ,从 n - 1 到 0循环,内层放 S,从 1 到 (1<<n)-1循环,当S包含 i 时,则DP[S][i]=DP[S][i+1]。

如果S不包含 i ,就循环其他所有点 j (i != j),

DP[S][i]=min(DP[S][i],DP[S 添加 i 添加 j][i+1]+i和j组成的矩形面积)

思路可以了,但欠缺一点,有时候一个矩形会覆盖两个点。

这种情况仅在两个点同行或同列的情况出现,否则是下图

那么加个判断,如果两个点是同一条直线,它们之间的矩形为零的那条边设置长度为1。同时连一条边的时候,判断是否有其他点是否也在矩形内的,记录它们到集合child里,更改递推式为

DP[S][i]=min(DP[S][i],DP[S 添加 i 添加 j 添加child内所有的元素][i+1]+i和j组成的矩形面积)

(这里只判断 i 之后的点是否在范围内即可,因为之前的不会影响到DP[XXX][i+1]之后的值)

循环集合时,要跳过确定已经连了的部分来提速。

三、代码

#include <iostream>
#include <algorithm>
#include <string.h>
using namespace std;
struct P
{
    int x, y;
    P(int x = 0, int y = 0) : x(x), y(y) {}
};
bool compare(P &a, P &b)
{
    return a.y != b.y ? a.y > b.y : a.x < b.x;
}
const int MAX_N = 15;
const int INF = 0x3f3f3f3f;
int dp[2][1 << MAX_N];
P dat[15];
int n;
int *crt = dp[0], *nxt = dp[1];
void solveItem(int i, int used)
{
    if (used >> i & 1)
    {
        nxt[used] = crt[used];
        return;
    }
    nxt[used] = INF;
    for (int j = 0; j < n; j++)
    {
        if (i == j)
        {
            continue;
        }
        int w = abs(dat[i].x - dat[j].x);
        int h = abs(dat[i].y - dat[j].y);
        int x1 = min(dat[i].x, dat[j].x);
        int y1 = min(dat[i].y, dat[j].y);
        int area = (w > 0 ? w : 1) * (h > 0 ? h : 1);
        int child = 0;
        for (int k = i + 1; k < n; k++)
        {
            if ((dat[k].x >= x1 && dat[k].x <= (x1 + w) && dat[k].y >= y1 && dat[k].y <= (y1 + h)) ||
                (w == 0 && dat[k].x >= (x1 - 1) && dat[k].x <= x1 && dat[k].y >= y1 && dat[k].y <= (y1 + h)) ||
                (h == 0 && dat[k].y >= (y1 - 1) && dat[k].y <= y1 && dat[k].x >= x1 && dat[k].x <= (x1 + w)))
            {
                child = child | (1 << k);
            }
        }
        nxt[used] = min(nxt[used], crt[used | (1 << i) | (1 << j) | child] + area);
    }
}
void solve()
{
    memset(dp, 0, sizeof(dp));
    int all = (1 << n) - 1;
    for (int i = n - 1; i >= 0; i--)
    {
        all = all & ~(1 << i);
        for (int S = 0; S < (1 << (n - i)); S++)
        {
            int used = all | (S << i);
            solveItem(i, used);
        }
        swap(crt, nxt);
    }
    printf("%d\n", crt[0]);
}
int main()
{
    while (true)
    {
        scanf("%d", &n);
        if (n == 0)
        {
            break;
        }
        for (int i = 0; i < n; i++)
        {
            scanf("%d%d", &dat[i].x, &dat[i].y);
        }
        sort(dat, dat + n, compare);
        solve();
    }
    return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/151611.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

实时云渲染技术在智慧园区中的广泛应用

智慧园区是指通过运用先进的信息技术&#xff0c;利用物联网、大数据、云计算等技术手段&#xff0c;来实现对园区内各类设备、设施和资源进行监测、管理、控制和优化的平台。这一概念旨在提高园区运行的效率、实现资源的可持续利用&#xff0c;并通过数字化和智能化手段来推动…

超级干货!如何挖公益SRC实战/SQL注入

目录 一、信息收集 二、实战演示 三、使用sqlmap进行验证 四、总结 一、信息收集 1.查找带有ID传参的网站&#xff08;可以查找sql注入漏洞&#xff09; inurl:asp idxx 2.查找网站后台&#xff08;多数有登陆框&#xff0c;可以查找弱口令&#xff0c;暴力破解等漏洞&…

Lombok超详解

目录 一、Lombok概述 二、Lombok插件安装 三、Lombok相关注解 3.1 Setter和Getter 3.2 ToString 3.3 EqualsAndHashCode&#xff0c;NonNull 3.4 NoArgsConstructor&#xff0c;RequiredArgsConstructor&#xff0c;AllArgsConstructor 3.5 Data 3.6 Builder 3.7 Log…

Python 如何实现桥接设计模式?什么是桥接(Bridge)设计模式?

什么是桥接&#xff08;Bridge&#xff09;设计模式&#xff1f; 桥接&#xff08;Bridge&#xff09;设计模式是一种结构型设计模式&#xff0c;它的主要目的是将抽象部分与实现部分分离&#xff0c;以便它们可以独立地变化。这种模式通过创建一个桥接接口&#xff0c;连接抽…

Node.js详解

一、是什么 Node.js 是一个开源与跨平台的 JavaScript 运行时环境 在浏览器外运行 V8 JavaScript 引擎&#xff08;Google Chrome 的内核&#xff09;&#xff0c;利用事件驱动、非阻塞和异步输入输出模型等技术提高性能 可以理解为 Node.js 就是一个服务器端的、非阻塞式I/…

使用 PPO 算法进行 RLHF 的 N 步实现细节

当下&#xff0c;RLHF/ChatGPT 已经变成了一个非常流行的话题。我们正在致力于更多有关 RLHF 的研究&#xff0c;这篇博客尝试复现 OpenAI 在 2019 年开源的原始 RLHF 代码库&#xff0c;其仓库位置位于 openai/lm-human-preferences。尽管它具有 “tensorflow-1.x” 的特性&am…

基于SSM的校园家教兼职信息交流平台设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

三行Python代码即可将视频转Gif

一、前言 很多网站提供视频转GIF的功能&#xff0c;但要么收费要么有广告 实际上我们通过python&#xff0c;几行代码就能够实现视频转gif 二、教程 1. 安装必备库moviepy pip install moviepy -i https://pypi.tuna.tsinghua.edu.cn/simple 2. 写入代码 from moviepy.edi…

盘点一款制作电子杂志的网站,小白也能快速上手

随着科技的进步&#xff0c;电子宣传册已经成为了企业宣传和推广的重要工具之一。它们不仅易于制作和更新&#xff0c;而且可以轻松地在网络上传播&#xff0c;让更多的人了解您的品牌和产品。 现在&#xff0c;给大家推荐一款FLBOOK在线制作电子杂志平台。无需任何专业的设计技…

手写LASSO回归python实现

import numpy as np from matplotlib.font_manager import FontProperties from sklearn.datasets import make_regression from sklearn.model_selection import train_test_split import matplotlib.pyplot as pltclass Lasso():def __init__(self):pass# 数据准备def prepar…

MQTT协议详解及在Android上的应用

MQTT协议详解及在Android上的应用 一、MQTT协议简介二、MQTT工作原理三、MQTT协议特点四、MQTT在Android上的应用4.1 准备工作4.2 示例代码 五、结论 本博客将全面介绍MQTT&#xff08;Message Queuing Telemetry Transport&#xff09;协议的基本概念、工作原理、特点以及在An…

转录组测序学习第二弹

安装软件 前面已经安装好了conda&#xff0c;那么我们现在需要安装我们后续需要用到的软件 1.先进入我们前面建立的虚拟环境中 conda activate my_env2.安装软件 conda install -y sra-tools conda install -y trimmomatic conda install -y cutadapt multiqc conda install…

MATLAB 状态空间设计 —— LQG/LQR 和极点配置算法

系列文章目录 文章目录 系列文章目录前言一、相关函数 —— LQG/LQR 和极点配置算法1.1 LQR —— lqr 函数1.1.1 函数用法1.1.2 举例1.1.2.1 倒摆模型的 LQR 控制 1.2 LQG —— lqg() 函数1.2.1 函数用法1.2.2 举例 前言 状态空间控制设计方法&#xff0c;如 LQG/LQR 和极点配…

Google play个人开发者账号最新政策要求——必须20人连续14天封闭测试

前几天&#xff0c;Google play官方宣布了一项针对个人开发者账号发布新应用的政策要求&#xff0c;即从2023年11月13日后注册的个人开发者账号&#xff0c;其应用必须满足特定的测试要求&#xff0c;才能在 Google Play 中上架。 该政策表示&#xff0c;如果开发者使用的是20…

Java相关编程思想

少用继承多用“组合”——在现有类的基础上组织一个新类。 2.继承要用“is”来检验&#xff0c;如果继承者is被继承者&#xff0c;说明这是一个比较好的继承。 3.向上造型&#xff0c;把实现方法留给继承者去实现。&#xff08;动态绑定&#xff09; 4.把接口理解为抽象类的进一…

第一百七十四回 如何创建扇形渐变背景

文章目录 1. 概念介绍2. 实现方法3. 代码与效果3.1 示例代码3.2 运行效果 4. 内容总结 我们在 上一章回中介绍了"如何创建线性渐变背景"相关的内容&#xff0c;本章回中将介绍" 如何创建扇形渐变背景"。闲话休提&#xff0c;让我们一起Talk Flutter吧。 …

Python 如何实现适配器设计模式?什么是适配器(Adapter)设计模式?

什么是适配器设计模式&#xff1f; 适配器&#xff08;Adapter&#xff09;设计模式是一种结构型设计模式&#xff0c;它允许接口不兼容的类之间进行合作。适配器模式充当两个不兼容接口之间的桥梁&#xff0c;使得它们可以一起工作&#xff0c;而无需修改它们的源代码。 主要…

CTFhub-RCE-过滤空格

1. 查看当前目录&#xff1a;127.0.0.1|ls 2. 查看 flag_890277429145.php 127.0.0.1|cat flag_890277429145.php 根据题目可以知道空格被过滤掉了 3.空格可以用以下字符代替&#xff1a; < 、>、<>、%20(space)、%09(tab)、$IFS$9、 ${IFS}、$IFS等 $IFS在li…

03.智慧商城——封装请求模块、登录静态页面、图形验证码

01. 登录页静态布局 (1) 准备工作 新建 styles/common.less 重置默认样式 // 重置默认样式 * {margin: 0;padding: 0;box-sizing: border-box; }// 文字溢出省略号 .text-ellipsis-2 {overflow: hidden;-webkit-line-clamp: 2;text-overflow: ellipsis;display: -webkit-box…

C++标准模板(STL)- 类型支持 (属性查询,获取类型的对齐要求)

类型特性 类型特性定义一个编译时基于模板的结构&#xff0c;以查询或修改类型的属性。 试图特化定义于 <type_traits> 头文件的模板导致未定义行为&#xff0c;除了 std::common_type 可依照其所描述特化。 定义于<type_traits>头文件的模板可以用不完整类型实例…