ACM:每日学习 状压dp

状压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]);
}

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

那就这样吧。~

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

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

相关文章

02-编程猜谜游戏

本章通过演示如何在实际程序中使用 Rust&#xff0c;你将了解 let 、 match 、方法、关联函数、外部crate等基础知识。 本章将实现一个经典的初学者编程问题&#xff1a;猜谜游戏。 工作原理如下&#xff1a;程序将随机生成一个介于 1 和 100 之间的整数。然后&#xff0c;程序…

【算法实验】实验六

实验6-1 硬币找钱问题—贪心 问题描述&#xff1a; 设有6 种不同面值的硬币&#xff0c;各硬币的面值分别为5 分&#xff0c;1 角&#xff0c;2 角&#xff0c;5 角&#xff0c;1 元&#xff0c;2 元。现要用这些面值的硬币来购物和找钱。购物时可以使用的各种面值的硬币个数存…

CHS_01.2.2.1+调度的概念、层次

CHS_01.2.2.1调度的概念、层次 调度的概念、层次知识总览调度的基本概念调度的三个层次——高级调度![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/6957fdec179841f69a0508914145da36.png)调度的三个层次——低级调度调度的三个层次——中级调度补充知识&#xff…

Wheeltec小车的开发实录(1)

sudo mount -t nfs 192.168.58.101:/home/wheeltec/wheeltec_robot /mnt 报错 mount: /mnt: bad option; for several filesystems (e.g. nfs, cifs) you might need a /sbin/mount.<type> helper program. 解决办法 主机和从机都要安装 nfs-utils 安装nfs-utils su…

Android Termux技能大揭秘:安装MySQL并实现公网远程连接

&#x1f308;个人主页&#xff1a;聆风吟 &#x1f525;系列专栏&#xff1a;网络奇遇记、Cpolar杂谈 &#x1f516;少年有梦不应止于心动&#xff0c;更要付诸行动。 文章目录 &#x1f4cb;前言一. 安装MariaDB二. 安装cpolar内网穿透工具三. 创建安全隧道映射mysql四. 公网…

25计算机考研408专业课复习计划

点击蓝字&#xff0c;关注我们 今天要分享的是25计算机考研408专业课复习计划。 以下内容供大家参考&#xff0c;大家要根据自己的复习情况进行适当调整。 统考与自命题 统考科目是指计算机学科专业基础综合&#xff08;408&#xff09;&#xff0c;满分150分&#xff0c;试…

tomcat原理模拟和tomcat优化

1、tomcat实现原理 servlet 没有主方法main&#xff0c;依赖tomcat才能运行&#xff0c;因为tomcat 有主方法main&#xff0c;由java编写 servlet中doGet和doPost方法属于非静态方法&#xff0c;只能依托new对象存在&#xff0c;tomcat无法new出来对象&#xff0c;因此tomcat…

NLP论文阅读记录 - 2021 | WOS 使用预训练的序列到序列模型进行土耳其语抽象文本摘要

文章目录 前言0、论文摘要一、Introduction1.1目标问题1.2相关的尝试1.3本文贡献 二.相关工作2.1 预训练的序列到序列模型2.2 抽象文本摘要 三.本文方法3.1 总结为两阶段学习3.1.1 基础系统 3.2 重构文本摘要 四 实验效果4.1数据集4.2 对比模型4.3实施细节4.4评估指标4.5 实验结…

一文读懂JavaScript DOM节点操作(JavaScript DOM节点操作详解)

一、什么是节点 二、节点类型 1、元素节点 2、属性节点 3、文本节点 4、节点类型、名字、值表格 三、通过文档对象方法获取节点 1、通过id属性获取节点 2、通过标签名字获取节点 3、通过类名获取节点 4、通过name属性获取节点 四、通过层级关系获取节点 1、子节点 …

【Flink-CDC】Flink CDC 介绍和原理概述

【Flink-CDC】Flink CDC 介绍和原理概述 1&#xff09;基于查询的 CDC 和基于日志的 CDC2&#xff09;Flink CDC3&#xff09;Flink CDC原理简述4&#xff09;基于 Flink SQL CDC 的数据同步方案实践4.1.案例 1 : Flink SQL CDC JDBC Connector4.2.案例 2 : CDC Streaming ETL…

从 Context 看 Go 设计模式:接口、封装和并发控制

文章目录 Context 的基本结构Context 的实现和传递机制为什么 Context 不直接传递指针案例&#xff1a;DataStore结论 在 Go 语言中&#xff0c; context 包是并发编程的核心&#xff0c;用于传递取消信号和请求范围的值。但其传值机制&#xff0c;特别是为什么不通过指针传递…

【大数据分析与挖掘技术】概述

目录 一、数据挖掘简介 &#xff08;一&#xff09;数据挖掘对象 &#xff08;二&#xff09;数据挖掘流程 &#xff08;三&#xff09;数据挖掘的分析方法 &#xff08;四&#xff09;经典算法 二、Mahout &#xff08;一&#xff09;Mahout简介 &#xff08;二&#…

CVE-2023-46226 Apache iotdb远程代码执行漏洞

项目介绍 Apache IoTDB 是针对时间序列数据收集、存储与分析一体化的数据管理引擎。它具有体量轻、性能高、易使用的特点&#xff0c;完美对接 Hadoop 与 Spark 生态&#xff0c;适用于工业物联网应用中海量时间序列数据高速写入和复杂分析查询的需求。 项目地址 https://io…

【INTEL(ALTERA)】F-tile 参考时钟和系统 PLL 时钟英特尔® FPGA IP无法锁定在特定频率?

说明 由于在英特尔 Quartus Prime Pro Edition 软件 22.2 及更早版本中存在一个问题&#xff0c;您可能会观察到 F-tile 参考时钟和系统 PLL 时钟英特尔 FPGA IP无法锁定&#xff1a; 999.9 MHz&#xff0c;参考时钟频率设置为 323.2 MHz。506.88 MHz&#xff0c;参考时钟频率…

Windows系统使用手册

点击前往查看&#x1f517;我的博客文章目录 Windows系统使用手册 文章目录 Windows系统使用手册Windows10解决大小核调度问题Windows系统安装软件Windows系统Typora快捷键Windows系统压缩包方式安装redisWindows安装dockerWindows系统的docker设置阿里源Windows系统下使用doc…

Ubuntu系统pycharm以及annaconda的安装配置笔记以及问题集锦(更新中)

Ubuntu 22.04系统pycharm以及annaconda的安装配置笔记以及问题集锦 pycharm安装 安装完之后桌面上并没有生成图标 后面每次启动pycharm都要到它的安装路径下的bin文件夹下&#xff0c; cd Downloads/pycharm-2018.1.4/bin然后使用sh命令启动脚本程序来打开pycharm sh pycha…

01 MyBatisPlus快速入门

1. MyBatis-Plus快速入门 版本 3.5.31并非另起炉灶 , 而是MyBatis的增强 , 使用之前依然要导入MyBatis的依赖 , 且之前MyBatis的所有功能依然可以使用.局限性是仅限于单表操作, 对于多表仍需要手写 项目结构&#xff1a; 先导入依赖&#xff0c;比之前多了一个mybatis-plus…

动态规划汇总

作者推荐 视频算法专题 简介 动态规划&#xff08;Dynamic Programming&#xff0c;DP&#xff09;是运筹学的一个分支&#xff0c;是求解决策过程最优化的过程。每次决策依赖于当前状态&#xff0c;又随即引起状态的转移。一个决策序列就是在变化的状态中产生出来的&#x…

《WebKit 技术内幕》之五(2): HTML解释器和DOM 模型

2.HTML 解释器 2.1 解释过程 HTML 解释器的工作就是将网络或者本地磁盘获取的 HTML 网页和资源从字节流解释成 DOM 树结构。 这一过程中&#xff0c;WebKit 内部对网页内容在各个阶段的结构表示。 WebKit 中这一过程如下&#xff1a;首先是字节流&#xff0c;经过解码之…

力扣每日一练(24-1-20)

大脑里的第一想法是排列组合&#xff0c;直接给出超级准确的最优解。 但不适用&#xff0c;hhh 只要连续的n个元素大于或者等于target就可以了 题目比自己想象的要好解决 解法是使用滑动窗口算法。这个算法的基本思想是维护一个窗口&#xff0c;使得窗口内的元素总和大于等于目…