ACM:每日学习 状压dp

news2024/11/20 11:43:38

状压dp:

状压dp是对一般dp的改进:

//对于判断多种物品的取法,开多维数组比较麻烦,也不好开,使用二进制来表示物品的取与否。

//使用二进制的话,位运算就更能省时间了,而且更会节省空空间,敲数组也比较好敲,唯一比较难的就是位运算真是费大脑。一定要熟练的运用位运算,建议看看这个。位运算全面总结,关于位运算看这篇就够了-CSDN博客

状压dp算法的前提:

1.看看是不是有多个要取的数(不一定是多个物品,可能是一个数的每位数要取与否)一定要记录当前下标的状态和上一个节点所取的点,并且记录二进制的点,个数就是2^n(n为要取的物品),所以状压dp大部分是二维数组。

2.再者计算一下时间复杂度,看看n是不是在20左右(因为2^20为100w)要是再有多重循环的话,差不多就10^8了,正好到了计算机1s运算量了。

3.dp的基本特征吧,前面取得的会影响后面要取的。

接下来实战一下,毕竟实战比理论更容易记忆。

例题1:吃奶酪 - 洛谷

这个题目的话是要你求要吃奶酪的最短距离,其中包括n个点这就是多个物品的情况。这个题目的话题意还是比较好理解的,你要做的就是记录上一个点的位置和这个点的位置,循环求这个点到上个点的最短距离,但是你要求的是全局,而不只是单独求一个最短的距离,那么就是dp啦,从多种情况中取得最短的距离,就要最后二进制全部取1之后再循环一遍for(int i;i<=n;i++)求得ans最小。

首先把大体的框架想了一遍然后开始想想如何实现dp了。其实dp就是模板,重要的是二进制的位运算记录。for(int i=0;i<(1<<(n+1));i++)最重要的一步啊。

再者就是要想想如何简便地求距离,我偷学了一招啊,PDD(pair<double,double)(因为是距离,再者点有是实数,得用double,这不是玩梗),用pair存点非常的好用,再随便写个函数来计算就行了。

代码实现:

//洛谷:吃奶酪
//二维的?分别存储奶酪状态和落脚点
//一共有几块dp(2^n-1)
#include <bits/stdc++.h>
using namespace std;
const int N = 17;
#define PDD pair<double, double>
PDD a[N];
double dp[1 << N][N];
// 计算距离
double dis(PDD l, PDD r){
    double dx = l.first - r.first;
    double dy = l.second - r.second;
    return sqrt(dx * dx + dy * dy);
}
signed main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int n,i, j, k, g;
    cin >> n;
    for (int i = 1; i <= n; i++)
        cin >> a[i].first >> a[i].second;
    memset(dp, 127, sizeof dp);
    dp[1][0] = 0;
    for (i = 0; i < (1 << (n + 1)); i++){
        if (i & 1)
            for (j = 1; j <= n; j++){
                if (i & (1 << j)){
                    k = i ^ (1 << j);
                    for (g = 0; g <= n; g++)
                        if (k & (1 << g))
                            dp[i][j] = min(dp[i][j], dp[k][g] + dis(a[j], a[g]));
                }
            }
    }
    double ans = 1000000000;
//或者可以改成 db ans=-1,下面写if(ans=-1||ans>dp[(1<<(n+1))-1][i])ans=dp[(1<<(n+1))-1][i];
    for (int i = 1; i <= n; i++){
        ans = min(ans, dp[(1 << (n + 1)) - 1][i]);
    }
    printf("%.2lf\n", ans);
}

接下来我本来想写那个非常经典的题目的,但是由于非常复杂,我还没有完全明白,所以再来个别的例题吧。

例题2:[蓝桥杯 2019 省 A] 糖果 - 洛谷

一看到折磨多的糖果种类和要求的最小值就一定是状压dp啊。

这一题目也是经典啊,对于未给定每包的糖果数量我们可以先将每包糖果压缩为一个二进制的数,再一一地去用for(int j=0;j<(1<<m);j++)来一步步的加糖果袋dp[j|a[i]]就是当前的糖果状态所需要的糖果数量,而dp[(1<<m)-1]是最终2^m-1的全部糖果的状态,此时判断dp数组是否等于设的初值来判断是否能吃到全部的糖果。

代码实现:

#include<bits/stdc++.h>
using namespace std;
#define int long long 
const int N=20;
int a[1<<N]={0};
int dp[1<<N];
int n,m,k;//n糖果包数、m糖果种类、k每包糖果的糖果数
signed main(){
    scanf("%d%d%d",&n,&m,&k);
    int num=(1<<m);
    memset(dp,0x3f3f3f3f,sizeof dp);//划分界限
    for(int i=1;i<=n;i++){
        for(int j=1;j<=k;j++){
           int t;
           scanf("%d",&t);
           a[i]=a[i]|(1<<(t-1));//将每包的糖果压缩
        }
        dp[a[i]]=1;
    }
    for(int j=0;j<num;j++)
       for(int i=1;i<=n;i++){
        // dp[j|a[i]]=((dp[j]|a[i])<dp[j]+1)?dp[j|a[i]]:dp[j]+1;
        //条件运算符?:表达式1true结果为表达式2,false结果为表达式3
        dp[j|a[i]]=min(dp[j|a[i]],dp[j]+1);//j|a[i]是用来加糖果的(|同0则0)
       }
    if(dp[num-1]==0x3f3f3f3f)printf("-1");
    else printf("%d\n",dp[num-1]);
}

以上就是比较典型的题目了,还有一种就是给你一个固定的大区域分成几个固定的小区域求分法。这种题型等之后学会在看看能不能发一下。

那就这样吧。~

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

3D Guassians Splatting相关解读

从已有的点云模型出发&#xff0c;以每个点为中心&#xff0c;建立可学习的高斯表达&#xff0c;用Splatting即抛雪球的方法进行渲染&#xff0c;实现高分辨率的实时渲染。 1、主要思想 1.引入了一种各向异性&#xff08;anisotropic&#xff09;的3D高斯分布作为高质量、非结…

实战 php 使用 wkhtmltopdf 生成pdf的全过程

公司里边有生成pdf报告的业务需求,之前有过尝试用tcpdf,直接生成的pdf的过程,但是pdf报告的内容数据,根据不同内容的变化,都是各种各样的bug,一直处理修修补补的状态,让后台开发人员很是头疼. 经过思索和甄选,总结出我们的业务中是由于样式不可控导致的,当时从逻辑上就思考到用…

CHS_06.2.1.6_2+线程的实现方式和多线程模型

CHS_06.2.1.6_2线程的实现方式和多线程模型 知识总览线程的实现方式用户级线程&#xff08;User-Level Thread, ULT&#xff09;内核级线程 多线程模型一对一模型多对一多对多模型 知识回顾 在上个小节中 我们学习了线程相关的一些基本概念 基础的知识 那这个小节中 我们回来看…

人脸识别打卡系统的设计与应用!人脸识别打卡系统有什么用?

教育行业的快速日新月异&#xff0c;对信息化建设的要求也越来越高。学校物业管理成为保障学校正常运行的重要环节。然而&#xff0c;在实践中&#xff0c;由于服务人员数量不足、管理不规范等问题&#xff0c;服务质量往往难以保证物业对学校师生的服务质量。为了解决这一问题…

如果你正在学自动化测试,那么请你仔细看完这篇文章

接触了不少同行&#xff0c;由于他们之前一直做手工测试&#xff0c;现在很迫切希望做自动化测试&#xff0c;其中不乏工作5年以上的人。 本人从事软件自动化测试已经近5年&#xff0c;从server端到web端&#xff0c;从API到mobile&#xff0c;切身体会到自动化带来的好处与痛楚…

高级 Python 面试问题与解答

文章目录 专栏导读1.什么是PIP&#xff1f;2.什么是 zip 函数&#xff1f;3.Python 中的 __init __ () 是什么&#xff1f;4.Python 中的访问说明符是什么&#xff1f;5.Python 中的单元测试是什么&#xff1f;6.Python全局解释器锁&#xff08;GIL&#xff09;&#xff1f;7.P…

linux yum仓库

yum是基于rpm包构建的软件更新机制&#xff0c;能够自动解决软件包之间的依赖关系。 常用命令 查询 yum list [软件名] 显示可用的安装包&#xff0c;如果不加软件名则显示所有的可用包 yum info [软件名] 显示安装包的详细信息 如果不加软件名是显示所有包…

CF1178F2 Long Colorful Strip 题解 搜索

Long Colorful Strip 传送门 题面翻译 题目描述 这是 F 题的第二个子任务。F1 和 F2 的区别仅在对于 m m m 和时间的限制上 有 n 1 n1 n1 种颜色标号从 0 0 0 到 n n n&#xff0c;我们有一条全部染成颜色 0 0 0 的长为 m m m 的纸带。 Alice 拿着刷子通过以下的过…

MybatisPlus框架入门级理解

MybatisPlus 快速入门入门案例常见注解常用配置 核心功能条件构造器自定义SQLService接口 快速入门 入门案例 使用MybatisPlus的基本步骤&#xff1a; 1.引入MybatisPlus的起步依赖 MybatisPlus官方提供了starter&#xff0c;其中集成了Mybatis和MybatisPlus的所有功能&#…

Spring Cloud 微服务中 gateway 网关如何设置健康检测端点

主要是为了让 k8s 识别到网关项目已经就绪&#xff0c;但是又不想在里面通过 Controller 实现。因为在 Controller 中这样做并不是最佳实践&#xff0c;因为 Gateway 的设计初衷是专注于路由和过滤&#xff0c;而不是业务逻辑的处理。 在 Gateway 中配置健康检查端点可以通过以…

QT报错记录

Ubuntu22.04安装Qt之后启动Qt Creator报错&#xff1a; Fron 6.5.0, xcb-cursor0 or libxcb-cursor0 is needed to load the Qt xcb platforn plugin. Could not load. This application failed to start because no Qt platforn plugin could be initialized. Reinstalling t…

Qt vs开发将Graphics view提升 QChartview

1提升部件 2 添加Charts模块 3 在包含ui类的头文件添加QT_CHARTS_USE_NAMESPACE 或者添加 using namespace QtCharts #include <QtWidgets/QMainWindow> #include <QtCharts> #include "ui_mainwin.h" #include <qchartview.h> QT_CHARTS_USE_N…

k8s---pod控制器

pod控制器发的概念&#xff1a; 工作负载&#xff0c;workload用于管理pod的中间层&#xff0c;确保pod资源符合预期的状态。 预期状态&#xff1a; 1、副本数 2、容器重启策略 3、镜像拉取策略 pod出故障的出去等等 pod控制器的类型&#xff1a; 1、replicaset&#xf…

Star 72.4k!神仙级开源项目,真的一行代码都没有!

前言 在 GitHub 开源社区&#xff0c;我们经常能发现一些优秀的开源高分项目&#xff01;有时候为了找到最优秀的开源项目&#xff0c;却往往要在 GitHub 上搜罗很久&#xff0c;很消耗时间。 今天小编就给大家推荐一个近乎于完美的 GitHub 中文排行榜&#xff0c;在这里&…

java基础之线程练习题

1.关于线程设计&#xff0c;下列描述正确的是&#xff08;&#xff09; A.线程对象必须实现Runnable 接口 B.启动一个线程直接调用线程对象的 run()方法 C.Java 对多线程同步提供语言级的支持 synchronized D.一个线程可以包括多个进程 2.在java 中的线程模型包含&#xff0…

【刷题】leetcode 1 . 两数之和

两数之和 两数之和1 思路一 &#xff08;简单突破&#xff09;2 思路二 &#xff08;进行优化&#xff09;3 思路三 &#xff08;哈希表 我还不会&#xff09; 谢谢阅读Thanks♪(&#xff65;ω&#xff65;)&#xff89;下一篇文章见&#xff01;&#xff01;&#xff01; 两数…

发票系统对接诺诺平台

诺诺平台判断设备不在线&#xff0c;导致开票失败 代码方面优化&#xff1a;调用接口的时候&#xff1a;是否先调用在线状态检测接口&#xff0c;确认开票设备是在线的状态 &#xff0c;在调用诺诺平台&#xff0c;不在线直接拦截&#xff1b;例如&#xff1a;这个原理就类似于…

三使用Docker Hub管理镜像

使用Docker Hub管理镜像 Docker Hub是Docker官方维护的Docker Registry&#xff0c;上面存放着很多优秀的镜像。不仅如此&#xff0c;Docker Hub还提供认证、工作组结构、工作流工具、构建触发器等工具来简化我们的工作。 前文已经讲过&#xff0c;我们可使用docker search 命…

虚拟机连接(与主机断开连接)U盘的按钮为灰色之解决方法

在WIN11中&#xff0c;虚拟机“连接(与主机断开连接)U盘”选项为灰色&#xff0c;解决方法如下&#xff1a; 1、关闭虚拟机电源&#xff0c;得到下面的界面&#xff1a; 2、根据上述提示&#xff0c;找到虚拟机所在磁盘 3、配置文件属性见下图&#xff1a; 4、使用记事本打开…

C++力扣题目98--验证二叉搜索树

给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&#xff1a; 节点的左子树只包含 小于 当前节点的数。节点的右子树只包含 大于 当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。 示例 1&#xff1a; 输入…