洛谷 P3694 邦邦的大合唱站队 状压DP
题目描述

输入输出样例
输入 #1 复制
12 4
1
3
2
4
2
1
2
3
1
1
3
4
输出 #1 复制
7
说明/提示

分析
首先要注意合唱队排好队之后不一定是按\(1.2.3......m\)的顺序的
\(N\)的范围很大,但\(m\)的数据比较小,所以我们考虑装压DP
我们设\(f[i]\)为状态为\(i\)的合唱队已经安排好位置的最小花费
接下来就是状态转移方程的问题
for(int i=1;i<(1<<m);i++){
int len=0;
for(int j=1;j<=m;j++){
if(i&(1<<(j-1))) len+=num[j];
}
for(int j=1;j<=m;j++){
if(i&(1<<(j-1))) f[i]=min(f[i],f[i^(1<<(j-1))]+num[j]-sum[len][j]+sum[len-num[j]][j]);
}
}
第一维枚举的是状态,在枚举状态之后,我们还要统计当前状态下哪些合唱队已经排好了位置
我们用一个变量\(len\)记录排好队的总人数,如果当前合唱队已经排好了队,那么我们把总人数加上当前合唱队的人数
其中,编号为\(j\)的合唱队的总人数\(num[j]\)可以预处理
为什么这样做呢?
因为我们无论让偶像们怎么出队,他们最终的状态是确定的,肯定是一个合唱队的偶像站到一起,因此我们就可以统计排好队后当前区间的总长度
接下来就是状态转移
如果编号为\(j\)的合唱队在我们决策的范围之内,那我们就需要尝试将编号为\(j\)的合唱队的全体成员都放在队伍最后
那么此时我们就需要将编号为\(j\)的合唱队中不在区间\([len-num[j]+1,num[j]]\)的偶像移到该区间
此时的花费为\(num[j]-sum[len][j]+sum[len-num[j]][j]\)
其中\(sum[i][j]\)表示开始时前\(i\)个位置中编号为\(j\)的合唱队员的个数
问题就可以解决了
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=22,maxm=1e5+5;
int f[1<<maxn];
int num[maxn],sum[maxm][maxn];
int main(){
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
int aa;
scanf("%d",&aa);
num[aa]++;
for(int j=1;j<=m;j++) sum[i][j]=sum[i-1][j];
sum[i][aa]++;
}
memset(f,0x3f,sizeof(f));
f[0]=0;
for(int i=1;i<(1<<m);i++){
int len=0;
for(int j=1;j<=m;j++){
if(i&(1<<(j-1))) len+=num[j];
}
for(int j=1;j<=m;j++){
if(i&(1<<(j-1))) f[i]=min(f[i],f[i^(1<<(j-1))]+num[j]-sum[len][j]+sum[len-num[j]][j]);
}
}
printf("%d\n",f[(1<< m)-1]);
return 0;
}
洛谷 P3694 邦邦的大合唱站队 状压DP的更多相关文章
- P3694 邦邦的大合唱站队 (状压DP)
题目背景 BanG Dream!里的所有偶像乐队要一起大合唱,不过在排队上出了一些问题. 题目描述 N个偶像排成一列,他们来自M个不同的乐队.每个团队至少有一个偶像. 现在要求重新安排队列,使来自同一 ...
- 洛谷P3959 宝藏(NOIP2017)(状压DP,子集DP)
洛谷题目传送门 Dalao的题解多数是什么模拟退火.DFS剪枝.\(O(3^nn^2)\)的状压DP之类.蒟蒻尝试着把状压改进了一下使复杂度降到\(O(3^nn)\). 考虑到每条边的贡献跟它所在的层 ...
- 洛谷P1896 [SCOI2005]互不侵犯King【状压DP】
题目描述 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. 输入格式: 只有一行,包含两个数N,K ...
- 【洛谷 P1896】[SCOI2005]互不侵犯(状压dp)
题目链接 题意:在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附近的各一个格子,共8个格子. 这是道状压\(DP\)好题啊.. ...
- BZOJ 2734 洛谷 3226 [HNOI2012]集合选数【状压DP】【思维题】
[题解] 思维题,看了别人的博客才会写. 写出这样的矩阵: 1,3,9,... 2,6,18,... 4,12.36,... 8,24,72,... 我们要做的就是从矩阵中选出一些数字,但是不能选相邻 ...
- 【洛谷5492】[PKUWC2018] 随机算法(状压DP)
点此看题面 大致题意: 用随机算法求一张图的最大独立集:每次随机一个排列,从前到后枚举排列中的点,如果当前点加入点集中依然是独立集,就将当前点加入点集中,最终得到的点集就是最大独立集.求这个随机算法的 ...
- 洛谷P2396 yyy loves Maths VII【状压dp】
题目:https://www.luogu.org/problemnew/show/P2396 题意:有n个数,每次选择一个表示走$a[i]$步,每个数只能选一次. 最多有两个厄运数字,如果走到了厄运数 ...
- 洛谷 3112 [USACO14DEC]后卫马克Guard Mark——状压dp
题目:https://www.luogu.org/problemnew/show/P3112 状压dp.发现只需要记录当前状态的牛中剩余承重最小的值. #include<iostream> ...
- 洛谷 P7324 - [WC2021] 表达式求值(状压+dp)
题面传送门 现场人傻系列-- 首先建出 \(E\) 的表达式树,具体来说表达式的每一个叶子节点表示一个数组 \(A_i\),每一个非叶子节点都表示一次运算,它的值表示左右儿子进行该运算后得到的结果.这 ...
随机推荐
- Mysql添加索引及索引的优缺点
一.什么是索引? 索引是对数据库表中的一列或多列值进行排序的一种结构,使用索引可以快速访问数据库表中的特定信息. 二.索引的作用? 索引相当于图书上的目录,可以根据目录上的页码快速找到所需的内容,提高 ...
- vi命令总结
VI常用技巧 VI命令可以说是Unix/Linux世界里最常用的编辑文件的命令了,但是因为它的命令集众多,很多人都不习惯使用它,其实您只需要掌握基本命令,然后加以灵活运用,就会发现它的优势,并会逐 ...
- WinForm通用自动更新AutoUpdater项目实战
目前我们做的上位机项目还是以Winform为主,在实际应用过程中,可能还会出现一些细节的修改.对于这种情况,如果上位机带有自动更新功能,我们只需要将更新后的应用程序打包放在指定的路径下,可以让用户自己 ...
- Spring之多数据源切换的应用
这不是一个新的知识点扩展,顶多算是,Spring的AOP特性的一个应用.那么下面开始今天的学习之旅! 场景 数据库读写分离,或者分库,总之多数据源的场景,怎么样实现自动切换(PS:不考虑各种分库分表的 ...
- ScrollView嵌套ConstraintLayout导致最后一项显示不全
原因:scrollView不受ConstraintLayout的约束布局影响 解决方法: 保持scrollview的宽高为0dp,设置其相对ConstraintLayout相对约束 <andro ...
- selenium(2)-selenium针对浏览器的操作有哪些
对浏览器有哪些操作 最大化.最小化浏览器 控制.获取浏览器大小 获取当前标签页title.url 前进.后退.刷新 执行js语句 打开.关闭,切换新标签页 滚动页面 上传附件 鼠标悬停 对话框的定位方 ...
- 采用Socket实现UDP
------------恢复内容开始------------ 1.1采用Socket实现UDP1.1.1简介 Socket实现UDP的基本步骤如下: (1)创建一个Socket对象 Socket my ...
- webpack入门进阶(3)
1.11.预处理器文件处理 1.sass文件 sass这种css预处理器是以.scss结尾,需要用node-sass和sass-loader来处理 安装loader npm i node-sass s ...
- node+ajax实战案例(2)
2.静态资源渲染 2.1.创建http服务器 var http = require('http'); var url = require('url'); var app = http.createSe ...
- P2194 HXY烧情侣【Tarjan】
前言 当时和\(GYZ\)大佬一起做这个题,他表示这个题对他很不友好(手动滑稽) 题目描述 众所周知,\(HXY\) 已经加入了 \(FFF\) 团.现在她要开始喜(sang)闻(xin)乐(bing ...