Codeforces 1215E. Marbles
注意到 $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的更多相关文章
- codeforces#1215E. Marbles(状压dp)
题目链接: http://codeforces.com/contest/1215/problem/E 题意: 至少多少次操作可以使得相同的数都是相邻的 每次操作可以交换两个相邻的数 数据范围: $1\ ...
- codeforces#1215E. Marbles(状压DP)
题目大意:给出一个由N个整数组成的序列,通过每次交换相邻的两个数,使这个序列的每个相同的数都相邻.求最小的交换次数. 比如给出序列:1 2 3 2 1 ,那么最终序列应该是 1 1 2 2 3 ,最小 ...
- Codeforces 608E. Marbles
E. Marbles time limit per test 2 seconds memory limit per test 256 megabytes input standard input ou ...
- Codeforces 1215E 状压DP
题意:给你一个序列,你可以交换序列中的相邻的两个元素,问最少需要交换多少次可以让这个序列变成若干个极大的颜色相同的子段. 思路:由于题目中的颜色种类很少,考虑状压DP.设dp[mask]为把mask为 ...
- CF-diary
(做题方式:瞟题解然后码) 1238E. Keyboard Purchase \(\texttt{Difficulty:2200}\) 题意 给你一个长度为 \(n\) 的由前 \(m\) 个小写字母 ...
- Codeforces Round #336 Marbles
E. Marbles time limit per test: 2 seconds memory limit per test: 256 megabytes input: standard in ...
- Codeforces Round #585 (Div. 2) E. Marbles (状压DP)
题目:https://codeforc.es/contest/1215/problem/E 题意:给你一个序列,你可以交换相邻的两个数,要达到一个要求,所有相同的数都相邻,问你交换次数最少是多少 思路 ...
- Codeforces Round #585 (Div. 2) E. Marbles(状压dp)
题意:给你一个长度为n的序列 问你需要多少次两两交换 可以让相同的数字在一个区间段 思路:我们可以预处理一个数组cnt[i][j]表示把i放到j前面需要交换多少次 然后二进制枚举后 每次选择一个为1的 ...
- Codeforces Round #585 (Div. 2) E. Marbles (状压DP),BZOJ大理石(同一道题)题解
题意 林老师是一位大理石收藏家,他在家里收藏了n块各种颜色的大理石,第i块大理石的颜色为ai.但是林老师觉得这些石头在家里随意摆放太过凌乱,他希望把所有颜色相同的石头放在一起.换句话说,林老师需要对现 ...
随机推荐
- HDU 3669 [Cross the Wall] DP斜率优化
问题分析 首先,如果一个人的\(w\)和\(h\)均小于另一个人,那么这个人显然可以被省略.如果我们将剩下的人按\(w[i]\)递增排序,那么\(h[i]\)就是递减. 之后我们考虑DP. 我们设\( ...
- openvas 安装
NMAP apt-get update & apt-get upgrade kali的更新命令 https://www.fujieace.com/kali-linux/update-sourc ...
- is == 编码与解码
is 和 == 主要是数字和字符串的比较 1 区别: ==比较的是两边的值 is比较的是两边值的id id获取的方法 id() 2 小数据池: -5~256 3 字符串中特殊字符有id ...
- 黑马lavarel教程---3、数据库和视图注意点
黑马lavarel教程---3.数据库和视图注意点 一.总结 一句话总结: 使用其实都很简单,MVC的框架都很像,用的时候直接可以去看手册,这样才能记得住 1.数据库删除操作注意? 删非删:很多网站的 ...
- Oracle数据库密码过期重置
oracle登陆密码过期了 这种情况,先连接Oracle,以Oracle用户登录,再输入以下命令: 1,linux系统下,以oracle用户登录进去: su - oracle 2,以系统dba身份登录 ...
- java面试要点
基础篇 基本功 面向对象的特征 final, finally, finalize 的区别 int 和 Integer 有什么区别 重载和重写的区别 抽象类和接口有什么区别 说说反射的用途及实现 说说自 ...
- Point-wise Mutual Information
Point-wise Mutual Information (Yao, et al 2019) reclaimed a clear description of Point-wise Mutual I ...
- linux如何查看目录或文件夹的总大小--du命令
记录一下如何查看一个目录或文件夹的总大小. 使用du命令的选项-s,可以统计整个目录或文件夹的大小. 例如 du -sk ./ 156k -k表示以KB为单位计算.
- [VBA]指定列求和
##指定列求和 需求: 求和:列为“销售金额”的数值 Sub 求和()Dim i As Integer, j As IntegerFor i = 3 To 56For j = 15 To 81 Ste ...
- ControlTemplate in WPF —— ListBox
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" x ...