题目大意:给出一个由N个整数组成的序列,通过每次交换相邻的两个数,使这个序列的每个相同的数都相邻。求最小的交换次数。

比如给出序列:1 2 3 2 1 ,那么最终序列应该是 1 1 2 2 3 ,最小交换次数为4.

输入格式

第一行输入一个数字n(2≤n≤4*10^5),表示大理石的总数。

第二行输入n个数字a1,a2…,an(1≤ai≤20)表示第i块大理石的颜色为ai。

输出格式

最少交换的次数。

样例

样例输入 1

7

3 4 2 3 4 2 2

样例输出 1

3

样例输入 2

5

20 1 14 10 2

样例输出 2

0

样例输入 3

13

5 5 4 4 3 5 7 6 5 4 4 6 5

样例输出 3

21

可以发现这道题的操作比较复杂,N的数量级也很大,\(N^2\)的时间复杂度肯定是行不通的。

对于这种题,我们可以先通过几组样例来构思出整道题的模型。

所以我们不妨考虑只有两种数的情况,对于数列 \(11221\),它的最终状态其实有两种\(11122\)和\(22111\)。我们统计每个数字2前面与它不同的数字的个数,分别是 2 + 2共需4次,这就是将所有的数字2全部移到左边所需要的次数,同理统计1的话只需2次。

现在我们来考虑多种数字的情况。我们发现这种情况不能直接通过上述方法来得出。但可以得到一个普遍的但不一定是最优的方法:

每次将一种数字全部移到左边,再将第二种数字全部移到左边(这时我们不能考虑第一种数字)。。。依次类推。

但每次移动哪种数字我们却不能确定,于是可以使用状压DP。

因为题目中\(1<=A_{i}<=20\)。设当前状态为S,如果S的第\(i\)位为1,则第\(i\)种颜色已经被选过,统计答案时便不需要统计第\(i\)种。

(大致思路已经给出,具体变量的含义请见注释)

#include <bits/stdc++.h>
using namespace std; #define N 400010
#define M 30
#define LL long long int A[N],n,pre[M][M];
LL f[1<<21];
vector<int> chos[M]; int main() {
cin>>n;
for(LL i=1;i<=n;i++) {
cin>>A[i];
chos[A[i]].push_back(i);//统计每种数字的下标,放入vector储存
}
//预处理
for(LL i=1;i<=20;i++)
for(LL j=1;j<=20;j++) {
if(i==j || chos[i].size()==0 || chos[j].size()==0) continue;
//统计答案
for(LL k=0,v;k<chos[i].size();k++) {
v=chos[i][k];
if(v<chos[j][0]) continue;
pre[i][j]+=lower_bound(chos[j].begin(),chos[j].end(),v)-chos[j].begin();
//二分查找离当前数字最近的指定的下标,这就是需要交换的次数,进行累加
}
}
memset(f,0x3f,sizeof(f));
f[0]=0;
for(LL i=0;i<(1<<20);i++)
for(LL j=1;j<=20;j++) //DP部分
if(!(i&(1<<(j-1)))) {
LL sum=0;
for(LL k=0;k<20;k++)
if(i&(1<<k))
sum+=pre[k+1][j];
f[i|(1<<(j-1))]=min(f[i|(1<<(j-1))],f[i]+sum);
}
cout<<f[(1<<20)-1];
}

codeforces#1215E. Marbles(状压DP)的更多相关文章

  1. E. Marbles 状压dp

    E. Marbles 这个是一个状压dp 题目大意是:给你一个数组,数组的数在1到20之间,有一个操作就是交换相邻的两个数,问 让所有相同的数相邻的最小操作次数 dp[s] 表示s状态下的操作次数,w ...

  2. codeforces 11D(状压dp)

    传送门:https://codeforces.com/problemset/problem/11/D 题意: 求n个点m条边的图里面环的个数 题解: 点的范围只有19,很容易想到是状压. dp[sta ...

  3. Codeforces Round #585 (Div. 2) E. Marbles(状压dp)

    题意:给你一个长度为n的序列 问你需要多少次两两交换 可以让相同的数字在一个区间段 思路:我们可以预处理一个数组cnt[i][j]表示把i放到j前面需要交换多少次 然后二进制枚举后 每次选择一个为1的 ...

  4. Codeforces 1215E 状压DP

    题意:给你一个序列,你可以交换序列中的相邻的两个元素,问最少需要交换多少次可以让这个序列变成若干个极大的颜色相同的子段. 思路:由于题目中的颜色种类很少,考虑状压DP.设dp[mask]为把mask为 ...

  5. Codeforces Round #585 (Div. 2) E. Marbles (状压DP),BZOJ大理石(同一道题)题解

    题意 林老师是一位大理石收藏家,他在家里收藏了n块各种颜色的大理石,第i块大理石的颜色为ai.但是林老师觉得这些石头在家里随意摆放太过凌乱,他希望把所有颜色相同的石头放在一起.换句话说,林老师需要对现 ...

  6. codeforces Diagrams & Tableaux1 (状压DP)

    http://codeforces.com/gym/100405 D题 题在pdf里 codeforces.com/gym/100405/attachments/download/2331/20132 ...

  7. Codeforces Gym 100015F Fighting for Triangles 状压DP

    Fighting for Triangles 题目连接: http://codeforces.com/gym/100015/attachments Description Andy and Ralph ...

  8. Codeforces Gym 100610 Problem K. Kitchen Robot 状压DP

    Problem K. Kitchen Robot Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/10061 ...

  9. 状压dp Codeforces Beta Round #8 C

    http://codeforces.com/contest/8/problem/C 题目大意:给你一个坐标系,给你一个人的目前的坐标(该坐标也是垃圾桶的坐标),再给你n个垃圾的坐标,这个人要捡完所有的 ...

随机推荐

  1. MySQl查询语句大全

    综合使用 查询 目录: #----综合使用 书写顺序 select distinct * from '表名' where '限制条件' group by '分组依据' having '过滤条件' or ...

  2. 关于session的记录

    在做DRP项目中的修改密码功能时,在JSP中先获取了之前登陆时设置的session中的用户账号,在调试的时候一直只是刷新页面,而没有重启页面,导致AJAX一直传输到相应的servlet失败,出现404 ...

  3. complementary error function

    首先正态分布的概率密度函数为: P{|X-μ|<σ}=2Φ(1)-1=0.6826,  P{|X-μ|<2σ}=2Φ(2)-1=0.9544,  P{|X-μ|<3σ}=2Φ(3)- ...

  4. amazon-aws 使用 SNS 发送短信

    jar-maven <!-- https://mvnrepository.com/artifact/com.amazonaws/aws-java-sdk-sns --> <depen ...

  5. xtrabackup备份mysql以及创建自动定时任务

    xtrabackup的安装 安装依赖关系 wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo y ...

  6. django之表单类

    一:表单类 一般我们在html中自己写的表单类似于下面的样子 <!DOCTYPE html> <html lang="en"> <head> & ...

  7. vue单页面项目中解决安卓4.4版本不兼容的问题

    1.cnpm安装 cnpm i babel-polyfill --save cnpm i es6-promise --save 2.main.js引入 import ‘babel-polyfill‘ ...

  8. man gzip

    GZIP(1)                                                                GZIP(1) NAME/名称       gzip, g ...

  9. k8s登录harbor报错:Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request cance

    [root@k8s-node02 ~]# docker login 192.168.180.105:1180 Username: admin Password: Error response from ...

  10. 基于点云的3ds Max快速精细三维建模方法及系统的制作方法 插件开发

                                 基于点云的3ds Max快速精细三维建模方法及系统的制作方法[技术领域][0001]本发明涉及数字城市三维建模领域,尤其涉及一种基于点云的3d ...