由于n较大,可以将n个数中的关系对数量记录在$m*m$的矩阵中,记作$a[i][j]$
考虑朴素的状压dp枚举排列,即$f[i]$表示以i中的数的一种排列为整个序列的前缀的最小代价,然后转移枚举下一个数j以及与其相关的数k,那么有转移$f[i|j]=\min(f[i]+(|i|+1)(\sum_{k\in i}\limits (t\cdot a[j][k]+a[k][j])+\sum_{k\notin i}\limits (t\cdot a[k][j]-a[j][k])))$,时间复杂度为$o(m^{2}\cdot 2^{m})$
对时间优化,对于一个i,需要快速求出下一个数为j时$|i|+1$的系数,设为$g[i][j]$,考虑从$i-lowbit(i)$转移,那么有转移$g[i][j]=g[i-k][j]+t\cdot a[j][k]+a[k][j]-(t\cdot a[k][j]-a[j][k])$,其中$k=lowbit(i)$,时间复杂度降为$o(m\cdot 2^{m})$,但空间复杂度变为$o(m\cdot 2^{m})$
对空间优化,有一个十分巧妙的做法:考虑g中修改1位的复杂度为$o(m)$,同时由于对0不断高精度+1加到$2^m$复杂度均摊$o(1)$,那么从小到大枚举i并对g暴力修改即可,时间复杂度不变,空间复杂度降为$o(2^{m}+m)$

 1 #include<bits/stdc++.h>
2 using namespace std;
3 int n,m,t,x,y,a[105][105],f[10000005],g[105];
4 int main(){
5 scanf("%d%d%d",&m,&n,&t);
6 for(int i=1;i<=m;i++){
7 scanf("%d",&y);
8 y--;
9 if (i>1)a[x][y]++;
10 x=y;
11 }
12 for(int i=0;i<n;i++)a[i][i]=0;
13 memset(f,0x3f,sizeof(f));
14 f[0]=0;
15 for(int i=0;i<(1<<n);i++){
16 int s=1,l=i-(i&(i-1));
17 for(int j=0;j<n;j++)s+=((i&(1<<j))>0);
18 for(int j=0;(1<<j)<=l;j++)
19 for(int k=0;k<n;k++)
20 g[k]=g[k]+(t*a[k][j]+a[j][k]+a[k][j]-t*a[j][k])*(1-2*((1<<j)<l));
21 if (!l)l=(1<<n);
22 for(int j=0;(1<<j)<=l;j++){
23 g[j]=0;
24 if ((1<<j)<l)
25 for(int k=0;k<n;k++)
26 if ((i&(1<<k))==0)g[j]+=t*a[k][j]-a[j][k];
27 else g[j]+=t*a[j][k]+a[k][j];
28 }
29 for(int j=0;j<n;j++)
30 if ((i&(1<<j))==0)f[i|(1<<j)]=min(f[i|(1<<j)],f[i]+s*g[j]);
31 }
32 printf("%d",f[(1<<n)-1]);
33 }

[loj3302]信号传递的更多相关文章

  1. 题解 P6622 [省选联考 2020 A/B 卷] 信号传递

    洛谷 P6622 [省选联考 2020 A/B 卷] 信号传递 题解 某次模拟赛的T2,考场上懒得想正解 (其实是不会QAQ), 打了个暴力就骗了\(30pts\) 就火速溜了,参考了一下某位强者的题 ...

  2. luoguP6622 [省选联考 2020 A/B 卷] 信号传递(状压dp)

    luoguP6622 [省选联考 2020 A/B 卷] 信号传递(状压dp) Luogu 题外话: 我可能是傻逼, 但不管我是不是傻逼, 我永远单挑出题人. 题解时间 看数据范围可以确定状压dp. ...

  3. linux 多线程之间信号传递

    函数 sigwait sigwait的含义就如同它的字面意思:等待某个信号的到来.如果调用该函数的线程没有等到它想等待的信号那么该线程就休眠.要达到等到一个信号,我们得做下面的事: 首先,定义一个信号 ...

  4. heoi2020信号传递

    状压dp 我状压学得是真烂..... 考试的时候想了状压,可是一直都是在枚举位置,没有神魔实质性突破.其实这道题的关键瓶颈也在于此,状压压的是号,而不是位置.如果 $i<=j$ 那么贡献为 $j ...

  5. P6622 信号传递 做题感想

    题目链接 前言 在这里分享两种的做法. 一种是我第一直觉的 模拟退火.(也就是骗分) 还有一种是看题解才搞懂的神仙折半搜索加上 dp . 模拟退火 众所周知,模拟退火 是我这种没脑子选手用来骗分的好算 ...

  6. Android面试题(一)

    1. 请描述一下Activity 生命周期. 答: 如下图所示.共有七个周期函数,按顺序分别是: onCreate(), onStart(), onRestart(), onResume(), onP ...

  7. 最快让你上手ReactiveCocoa之基础篇

    前言 很多blog都说ReactiveCocoa好用,然后各种秀自己如何灵活运用ReactiveCocoa,但是感觉真正缺少的是一篇如何学习ReactiveCocoa的文章,这里介绍一下. 1.Rea ...

  8. Altium Designer 的entry sheet ,offsheet和port作用(转载)

    1.图纸结构 图纸包括两种结构关系: 一种是层次式图纸,该连接关系是纵向的,也就是某一层次的图纸只能和相邻的上级或下级有关系: 另一种是扁平式图纸,该连接关系是横向的,任何两张图纸之间都可以建立信号连 ...

  9. Docker Volume 之权限管理(转)

    Volume数据卷是Docker的一个重要概念.数据卷是可供一个或多个容器使用的特殊目录,可以为容器应用存储提供有价值的特性: 持久化数据与容器的生命周期解耦:在容器删除之后数据卷中的内容可以保持.D ...

随机推荐

  1. 【Azure 云服务】Azure Cloud Service 为 Web Role(IIS Host)增加自定义字段 (把HTTP Request Header中的User-Agent字段增加到IIS输出日志中)

    问题描述 把Web Role服务发布到Azure Cloud Service后,需要在IIS的输出日志中,把每一个请求的HTTP Request Header中的User-Agent内容也输出到日志中 ...

  2. 试题 算法训练 二进制数数 java解题

    资源限制 时间限制:1.0s   内存限制:256.0MB 问题描述 给定L,R.统计[L,R]区间内的所有数在二进制下包含的"1"的个数之和. 如5的二进制为101,包含2个&q ...

  3. JavaScript 数组 常用方法(二)

    写在前面:续接上篇 JavaScript 数组 常用方法 数组常用方法第二弹来了: some && every 描述: every()与some()方法都是JS中数组的迭代方法. so ...

  4. Convolutional Neural Network-week1编程题(一步步搭建CNN模型)

    Convolutional Neural Networks: Step by Step implement convolutional (CONV) and pooling (POOL) layers ...

  5. Alpha-功能规格说明书

    项目 内容 这个作业属于哪个课程 2021春季软件工程(罗杰 任健) 这个作业的要求在哪里 团队项目-计划-功能规格说明书 一.引言 1. 项目简介 项目团队:删库跑路对不队 项目名称:题士 项目内容 ...

  6. java中的软,弱,虚引用介绍与特性分析

    java的弱,虚,软引用介绍 1.弱,虚,软引用的介绍 对于绝大部分的对象而言,在程序中是存在着一个引用变量引用该对象,这是常见的引用方式,也就是常说的 强引用,对于强引用引用的对象,系统JVM是不会 ...

  7. TVS管相关知识

    在设计中,使用到了TVS管,在之前的设计中没有特别关注TVS管.今天查了一些资料,算是简单的有个了解. TVS管是一种保护器件.它的英文全称为 transient voltage suppressor ...

  8. 玩转C语言链表-链表各类操作详解

    链表概述 链表是一种常见的重要的数据结构.它是动态地进行存储分配的一种结构.它可以根据需要开辟内存单元.链表有一个"头指针"变量,以head表示,它存放一个地址.该地址指向一个元素 ...

  9. 常用Java API:大数类

    摘要 java中的基础数据类型能存储的最大的二进制数是 2 ^ 63 - 1, 对应的十进制数是9223372036854775807,也就是说只要运算过程中会超过这个数,就会造成数据溢出,从而造成错 ...

  10. [CSP-S2021] 回文

    链接: P7915 题意: 给出一个长度为 \(2n\) 的序列 \(a\),其中 \(1\sim n\) 每个数出现了 2 次.有 L,R 两种操作分别是将 \(a\) 的开头或末尾元素加入到初始为 ...