传送门

注意到 $a$ 的值的数量并不大,考虑状压 $dp$

设 $f[S]$ 表示此时确定的数集合为 $S$ ,且按某种顺序从数列开头排列完成的最小交换次数

那么每个状态枚举最后一个填的数,加上代价后,取最小值即可

现在最大的问题是,代价怎么算...???

注意到我们每次交换相邻的两个数,这两个数和其他的数的相对位置是不变的(这个我认为是整题最关键的地方)

就是说在最优情况下,我们把数字 $x$ 统一交换到某个段时,产生的代价即为这个数原本每个位置和此时这个位置之前还没确定的数的数量....

讲得好绕啊,看代码比较好理解吧............

复杂度算一下达到了 $1e8$ 级别,但是 $CF$ 跑得快,这一题时限又长,所以很稳

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
typedef long long ll;
inline int read()
{
int x=,f=; char ch=getchar();
while(ch<''||ch>'') { if(ch=='-') f=-; ch=getchar(); }
while(ch>=''&&ch<='') { x=(x<<)+(x<<)+(ch^); ch=getchar(); }
return x*f;
}
const int N=4e5+,M=(<<)+;
int n,a[N],b[N],cnt[];
ll cst[][],f[M];
// cst[i][j] 表示把值i统一交换到值j之前的代价
int main()
{
n=read();
for(int i=;i<=n;i++) a[i]=read();
for(int i=;i<=n;i++)
{
for(int j=;j<=;j++)
cst[a[i]][j]+=cnt[j];
cnt[a[i]]++;
}
int mx=(<<)-;
memset(f,0x3f,sizeof(f)); f[]=;
for(int i=;i<=mx;i++)
for(int j=;j<;j++)
{
if(!((i>>j)&)) continue;
ll t=;
for(int k=;k<;k++)
{
if((i>>k)&) continue;
t+=cst[j+][k+];//代价和为 和此时还没确定的所有数交换的代价
}
f[i]=min(f[i],f[i^(<<j)]+t);
}
printf("%lld\n",f[mx]);
return ;
}

Codeforces 1215E. Marbles的更多相关文章

  1. codeforces#1215E. Marbles(状压dp)

    题目链接: http://codeforces.com/contest/1215/problem/E 题意: 至少多少次操作可以使得相同的数都是相邻的 每次操作可以交换两个相邻的数 数据范围: $1\ ...

  2. codeforces#1215E. Marbles(状压DP)

    题目大意:给出一个由N个整数组成的序列,通过每次交换相邻的两个数,使这个序列的每个相同的数都相邻.求最小的交换次数. 比如给出序列:1 2 3 2 1 ,那么最终序列应该是 1 1 2 2 3 ,最小 ...

  3. Codeforces 608E. Marbles

    E. Marbles time limit per test 2 seconds memory limit per test 256 megabytes input standard input ou ...

  4. Codeforces 1215E 状压DP

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

  5. CF-diary

    (做题方式:瞟题解然后码) 1238E. Keyboard Purchase \(\texttt{Difficulty:2200}\) 题意 给你一个长度为 \(n\) 的由前 \(m\) 个小写字母 ...

  6. Codeforces Round #336 Marbles

    E. Marbles time limit per test:  2 seconds memory limit per test:  256 megabytes input:  standard in ...

  7. Codeforces Round #585 (Div. 2) E. Marbles (状压DP)

    题目:https://codeforc.es/contest/1215/problem/E 题意:给你一个序列,你可以交换相邻的两个数,要达到一个要求,所有相同的数都相邻,问你交换次数最少是多少 思路 ...

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

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

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

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

随机推荐

  1. ovs-vsctl patch 连接两个网桥

    1.命令如下: ovs-vsctl add-port bridge-name port-name ovs-vsctl set interface port-name type=patch ovs-vs ...

  2. Struts2笔记(学struts2只需要这一篇文章)

    1.如何将struts2框架引入到web项目中      1.把struts2相关jar包引入到项目中 2.把struts2的配置文件直接放到src下面,名字要叫做struts.xml.(运行时配置文 ...

  3. [LOJ3120][CTS2019|CTSC2019]珍珠:生成函数+NTT

    分析 容易发现\(D \leq n - 2m\)时,任意数列都满足要求,直接判掉,下文所讨论的均为\(D > n - 2m\)的情况. 考虑把两个数列合并,显然可以认为是两个带标号对象的合并,可 ...

  4. [LOJ3119][CTS2019|CTSC2019]随机立方体:组合数学+二项式反演

    分析 感觉这道题的计数方法好厉害.. 一个直观的思路是,把题目转化为求至少有\(k\)个极大的数的概率. 考虑这样一个事实,如果钦定\((1,1,1),(2,2,2),...,(k,k,k)\)是那\ ...

  5. Spring Boot教程(三十二)多数据源配置与使用(2)

    Spring-data-jpa支持 对于数据源的配置可以沿用上例中DataSourceConfig的实现. 新增对第一数据源的JPA配置,注意两处注释的地方,用于指定数据源对应的Entity实体和Re ...

  6. HDU1257--最少拦截系统(DP)

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission( ...

  7. maven web项目的web.xml报错The markup in the document following the root element must be well-formed.

    maven项目里面的web.xml开头约束是这样的 <?xml version="1.0" encoding="UTF-8"?> <web-a ...

  8. spring-ApplicationContext的事件传播(转)

    ApplicationContext中的事件处理是通过ApplicationEvent类和ApplicationListener接口来提供的,通过ApplicationContext的publishE ...

  9. 套接字之 getsockname && getpeername

    getsockname-获取本地地址:比如,在绑定的时候设置端口号为0由系统自动选择端口绑定,或者使用了INADDR_ANY通配所有地址的情况下,后面需要用到具体的地址和端口,就可以用getsockn ...

  10. 【Spark机器学习速成宝典】模型篇01支持向量机【SVM】(Python版)

    目录 支持向量机原理 支持向量机代码(Spark Python) 支持向量机原理 详见博文:http://www.cnblogs.com/itmorn/p/8011587.html 返回目录 支持向量 ...