首页 > 编程语言 >状压DP(c++)

状压DP(c++)

时间:2024-09-08 15:21:16浏览次数:11  
标签:20 int double 奶酪 状压 c++ DP

好久都没来水博客了,现在闲的来写一篇刚学的状压DP思想

状压DP要把一个集合中的所有元素一一分别拿出来讨论,需要用到二进制保存集合状态

例如

110001010二进制,0代表没有,1代表有这个元素

876543210他的位置

所有状压dp差不多就一个思想

逐步将集合中的点包含进来

首先引入一道题目

洛谷P1433

题目描述

房间里放着 n 块奶酪。一只小老鼠要把它们都吃掉,问至少要跑多少距离?老鼠一开始在(0,0) 点处。

输出一行一个实数,表示要跑的最少距离,保留 2 位小数。

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
double a[20][20];//预处理第i块到j块的距离
double x[20],y[20];//每块的横纵坐标
double f[18][34000];//状压dp数组,在第i个点上,走过的二进制状态的十进制表达
//1100110001例如表示走过1,5,6,9,10块奶酪
//9876543210 
int n;
double dis(int v,int w)//计算两块奶酪的距离
{
    return sqrt((x[v]-x[w])*(x[v]-x[w])+(y[v]-y[w])*(y[v]-y[w]));
}
void solve() {
    int i,j,k;
    double ans;
    memset(f,127,sizeof(f));
    ans=f[0][0];
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>x[i]>>y[i];
    }
    x[0]=0;
    y[0]=0;
    for( i=0;i<=n;i++)
    {
        for( j=i+1;j<=n;j++)
        {
            a[i][j]=dis(i,j);
            a[j][i]=a[i][j];
        }
    }//初始化距离数组
    for(int i=1;i<=n;i++)//init
    {
        f[i][(1<<(i-1))]=a[0][i];//在i点上且只有经过i点时距离时原点到i点得距离
    }
    for(k=1;k<(1<<n);k++)//枚举所有二进制状态
    {
        for(i=1;i<=n;i++)//从小到大
        {
            if((k&((1<<(i-1))))==0)
            continue;
            for(j=1;j<=n;j++)//有点类似dj算法,a到b的路径可以为a->c->b
                //先取出其中包含的一个点取得路径
            {
                if(i==j)continue;
                if((k&(1<<(j-1)))==0)continue;
                f[i][k]=min(f[i][k],f[j][k-(1<<(i-1))]+a[i][j]);
            }

        }
    }
    for(int i=1;i<=n;i++)
    {
        ans=min(ans,f[i][(1<<n)-1]);
    }
    cout<<fixed<<setprecision(2)<<ans;
}
int main() 
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int t = 1;
    while (t--) {
        solve();
    }
    return 0;
}

标签:20,int,double,奶酪,状压,c++,DP
From: https://blog.csdn.net/charmfulpro/article/details/142027401

相关文章

  • C++STL之stack和queue容器适配器:基本使用及模拟实现
    目录stack的介绍和使用stack的介绍stack的使用queue的介绍和使用queue的介绍queue的使用priority_queue的介绍和使用priority_queue的介绍priority_queue的使用deque双端队列(容器)deque的介绍及使用deque的缺点deque的原理(了解)容器适配器概念stack和queue的......
  • C++ 模板进阶知识——完美转发
    目录C++模板进阶知识——完美转发1.完美转发的步骤演绎完美转发的关键点2.std::forward2.1工作原理2.2重要性3.普通参数的完美转发4.在构造函数模板中使用完美转发范例5.在可变参数模板中使用完美转发范例5.1常规的在可变参模板中使用完美转发5.2将目标函数......
  • c++标准库中对文件读写的函数与类
    在C++中,标准库提供了一组文件操作的函数和类,可以用来处理文件的读取、写入、打开、关闭等操作。主要使用的库是<fstream>和<cstdio>。以下是详细的举例说明:1.使用<fstream><fstream>提供了三个主要的类用于文件操作:std::ifstream:用于文件读取。std::ofstream:用于文......
  • Qt/C++音视频开发 - mpv解码播放
    Qt/C++音视频开发-mpv解码播放介绍一、应用使用场景Qt/C++结合mpv在音视频开发中的典型应用场景包括:媒体播放器:实现跨平台的高性能媒体播放器,支持各种音视频格式。实时流媒体播放:比如直播或视频会议系统的开发。媒体编辑工具:用于视频剪辑和音频编辑的软件。嵌入式系统:......
  • C++单例模式
    C++单例模式使用单例模式的理由在开发过程中,很多时候一个类我们希望它只创建一个对象,比如:线程池、缓存、网络请求等。当这类对象有多个实例时,程序就可能会出现异常,比如:程序出现异常行为、得到的结果不一致等。单例主要有这两个优点:提供了对唯一实例的受控访问。由于在系统内......
  • 【C++】vector的模拟实现
    文章目录一、前言二、构造函数模拟实现构造函数调用不明确1.问题描述2、解决调用不明确的方法三、基础接口1.empty和clear2.size和capacity3.[]和iterator四、resize和reservereserve中的深浅拷贝问题1、reserve中浅拷贝发生原因2、浅拷贝发生的图解3、解决方法五、尾......
  • 【C++】简述STL——string类的使用
    文章目录一、STL的简述1.STL的框架2.STL版本二、string1、string的介绍2、为什么string类要实现为模板?三、string的构造接口四、string的容量相关的接口五、string对象修改相关的接口1、insert2.earse3、assign4、replace六、string对象字符串运算相关接口1、c_str2、......
  • C++内存管理
    内存是什么?内存就是计算机的存储空间,用于存储程序的指令、数据和状态。在C语言中,内存被组织成一系列的字节,每个字节都有一个唯一的地址。程序中的变量和数据结构存储在这些字节中。根据变量的类型和作用域,内存分为几个区域,如栈(stack)、堆(heap)和全局/静态存储区。内存编址计算......
  • C++ STL-deque容器入门详解
    1.1deque容器基本概念功能:双端数组,可以对头端进行插入删除操作deque与vector区别:vector对于头部的插入删除效率低,数据量越大,效率越低deque相对而言,对头部的插入删除速度回比vector快vector访问元素时的速度会比deque快,这和两者内部实现有关deque内部工作原理:deque内部......
  • C++ STL-Map容器从入门到精通详解
    1.简介Map也是一种关联容器,它是键—值对的集合,即它的存储都是以一对键和值进行存储的,Map通常也可以理解为关联数组(associativearray),就是每一个值都有一个键与之一一对应,因此,map也是不允许重复元素出现的。同时map也具备set的相关功能,其底层也会将元素进行自动排序。功能......