当前位置: 首页 > news >正文

建设企业功能型网站网站的网站建设公司

建设企业功能型网站,网站的网站建设公司,响水县住房建设局网站,门户设计理念文章目录 简介做法洛谷 P1171 简介 状压 DP 其实约等于一个 DP 的小技巧,一般应用在处理一个或多个集合的问题中(因为状压 DP 的下标就是一个集合),而且在 n n n 太大的时候建议不要使用这种方法。(如果你不懂&#…

文章目录

  • 简介
  • 做法
    • 洛谷 P1171

简介

状压 DP 其实约等于一个 DP 的小技巧,一般应用在处理一个或多个集合的问题中(因为状压 DP 的下标就是一个集合),而且在 n n n 太大的时候建议不要使用这种方法。(如果你不懂,那么就继续往下看。好吧你本来就不懂。)

做法

状压 DP 的本质就是用一连串的 0 / 1 0/1 0/1 表示一个集合中的每一个元素的状态,一个 0 / 1 0/1 0/1 就对应一个元素的状态,它所组成的编码就很像二进制,所以状压 DP 的下标大小一般都是 2 n 2^n 2n(如果 n n n 很大,那么你就会收到一份 M L E \color{darkblue}{MLE} MLE 大礼包,好吧有时候是 C E \color{yellow}{CE} CE),用来保存当前这个集合的状态。

然后我们就可以用位运算来操作与处理,为了方便讲解,我们选择一道例题:

洛谷 P1171

某乡有 n ( 2 ≤ n ≤ 20 ) n\ (2\le n\le 20) n (2n20) 个村庄,有一个售货员,他要到各个村庄去售货,各村庄之间的路程 s ( 0 < s < 1000 ) s\ (0<s<1000) s (0<s<1000) 是已知的,且 A A A 村到 B B B 村与 B B B 村到 A A A 村的路大多不同。为了提高效率,他从商店出发到每个村庄一次,然后返回商店所在的村,假设商店所在的村庄为 1 1 1,他不知道选择什么样的路线才能使所走的路程最短。请你帮他选择一条最短的路。

这道题一看就知道肯定能写最短路,但是我们讲的是状压 DP,那就拿状压 DP 写吧。

首先确定下标是什么。状压 DP 下标的第一维肯定是当前状态,那是啥的状态呢?一看: n ≤ 20 n\le20 n20。这不妥妥的天生状压 DP 之体吗?所以状态就很简单了:当前这个点走没走过(也只能这么定义了,又不可能定义这个点存不存在,如果是这样的话那这个村子都没了还走个什么)。然后第二位就是图上 DP 的经典操作——当前在哪个点——了啊。一算总大小,刚好 1 0 7 = 10000000 10^7=10000000 107=10000000 左右( 2 20 = 1048576 2^{20}=1048576 220=1048576),不多不少。

那么 dp[i][j] 的定义自然就是在 i i i 这个状态下从第 1 1 1 个点到第 j j j 个点的最短距离。

其次就是状态转移方程了。首先状压 DP 的标配就是枚举当前状态,即从 00 … 0 ⏟ n 个  0 \underbrace{00\dots0}_{n\ \text{个}\ 0} n  0 000 11 … 1 ⏟ n 个  1 \underbrace{11\dots1}_{n\ \text{个}\ 1} n  1 111(在十进制下就是从 0 0 0 2 n − 1 2^n-1 2n1,这个减 1 1 1 的原因是因为二进制是从第 0 0 0 位开始算的,不是第 1 1 1 位,所以说最高位实际上是第 n − 1 n-1 n1 位,正好 2 n − 1 2^n-1 2n1 就有 n − 1 n-1 n1 位,且能极好的表达 11 … 1 ⏟ n 个  1 \underbrace{11\dots1}_{n\ \text{个}\ 1} n  1 111 这个数),这就是第一层循环。

其次肯定要枚举当前在哪个点。那对于当前所在的点我们就要进行分类讨论了:这个点在当前状态下走过还是没走过。现在我们不要管实际上是不是真的走过某个点,我们就认为当前这个状态就是对的。那走过的肯定不用说,走都走过了还有什么好更新的,关键在于没走过的。

没走过的我们就按照类似 Floyd 的方法,即给它找一个中转点(毕竟 Floyd 的本质不就是一个类似于 DP 的东西吗),所以我们只需要再浅浅的加一层循环找一个中转点,当然,这个中转点必须是当前状态下已经走过的点。(你自己都没走过还想帮别人。)

于是我们就可以写出一份伪代码:

memset(dp,0x3f3f3f3f,sizeof(dp));
dp[1][1]=0;//初始化:走过 1 且从 1 到 1 的距离等于没有距离(没走过一个点怎么走?)
for(int i=0;i<(1<<n);i++)
{for(int j=1;j<=n;j++){if(!((1<<j-1)&i)){for(int k=1;k<=n;k++){if((1<<k-1)&i){dp[i|(1<<j-1)][j]=min(dp[i|(1<<j-1)][j],dp[i][k]+a[k][j]);}}}}
}

有人会说:你这个时间复杂度一看就是 O ( 2 n × n 2 ) O(2^n\times n^2) O(2n×n2) 啊,这不包超时的吗?啊,其实是不会的,因为你看到第 5 5 5 行没有?这一句话会帮我省掉大部分循环,所以总体时间复杂度是肯定没有那么高的,是肯定不会超时的。

于是我们就可以写出完整代码:

#include<bits/stdc++.h>
using namespace std;
int n,ans=0x3f3f3f3f,a[26][26],dp[1050006][26];
signed main()
{cin>>n;for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){cin>>a[i][j];}}memset(dp,0x3f3f3f3f,sizeof(dp));dp[1][1]=0;for(int i=0;i<(1<<n);i++){for(int j=1;j<=n;j++){if(!((1<<j-1)&i)){for(int k=1;k<=n;k++){if((1<<k-1)&i){dp[i|(1<<j-1)][j]=min(dp[i|(1<<j-1)][j],dp[i][k]+a[k][j]);//中转一下}}}}}for(int i=2;i<=n;i++){ans=min(ans,dp[(1<<n)-1][i]+a[i][1]);//在经过了所有点的情况下最后走那个点路程最短呢?}cout<<ans;return 0;
}

以上就是状压 DP 的全部内容了。喜欢的同学们麻烦点个赞、收藏一下,我们下期再见。

http://www.dtcms.com/a/397684.html

相关文章:

  • 汽车网站建设参考文献开题报告爱企查官网
  • 网站做中英文切换上海 网站建设 外包
  • 长春企业模板建站室内装修设计软件免费版下载
  • 网站php怎么做的免费画图网站
  • 什么网站做电子元器件中国还有多少人没有打新冠疫苗
  • 南阳教育网站平台成都网站建设s1emens
  • 深圳商城网站设计多少钱wordpress主题偷
  • 广告优化师没经验怎么面试百度搜索结果优化
  • 建筑资料网站大全汉中网站网站建设
  • 怎么做 社区网站首页深圳做网站网络营销公司排名
  • 泉州网站建设公司首选响水哪家专业做网站
  • 虚拟主机网站wordpress 删除 加载中
  • 江苏网站建设空间甘肃兰州事件
  • 遵义本地网站建一个网站的技术解决方案
  • 网站建设需要什么专业张家口外贸网站建设
  • 电子商务网站建设与管理是什么最新网上注册公司流程
  • 做网站需要哪些知识北京美的网站
  • 青岛企业网站设计制作重庆网站搭建哪里可以做
  • 找别人做的网站怎样修改网站商城的意义
  • 做一个自己的免费网站电商运营方案计划书
  • 网站版权备案各种浏览器大全
  • 部队网站源码上海市住房和城乡建设部官方网站
  • 好网站目录下载并安装app
  • 租服务器去哪里租哈尔滨网站优化如何
  • 公文写作网站四川建设人才培训网站
  • 廊坊市建设银行网站成都百度推广公司联系方式
  • 我会编程怎么做网站网络推广
  • qq自动发货平台网站怎么做住房城乡建设网站藁城
  • php商城网站开发实例视频火车头wordpress教程
  • 科技 响应式网站模板阿里云企航域名购买方式