Description:

给定一个序列 \(a_i\) ,每次可以交换相邻两个元素,求使序列变成若干个极大连续段,每个极大连续段内部的值相同且任意两个极大连续段的值互不相同。

\(n\le 4\times 10^5, a_i\le 20\)

Solution:

由于值域很小,启发我们从值域入手,考虑每一种颜色。

设 \(cnt[i][j]\) 表示在只考虑颜色 \(i\) 和 \(j\) 的情况下,把所以颜色 \(i\) 都移到所有颜色 \(j\) 的前面的步数,这个对每一个颜色用 \(\text{vector}\) 存下出现的位置(从小到大),用 \({\rm two\ pointers}\) 扫一下即可求得 。

考虑状压每一种颜色,二进制下为1表示这个位的颜色已经被安排好了。

设 \(dp[S]\) 表示 \(S\) 的颜色已经安排好在序列的前面且两两不交的最小步数,那么转移就枚举一个不在 \(S\) 中的点 \(i\) ,把 \(i\) 放在考虑完的 \(S\) 的后面,那么产生的步数就是把 \(S\) 放在 \(i\) 的前面的步数,通过 \(cnt[][i]\) 可以求得。

Code:

#include <iostream>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <fstream> typedef long long LL;
typedef unsigned long long uLL; #define SZ(x) ((int)x.size())
#define ALL(x) (x).begin(), (x).end()
#define MP(x, y) std::make_pair(x, y)
#define DEBUG(...) fprintf(stderr, __VA_ARGS__)
#define GO cerr << "GO" << endl; using namespace std; inline void proc_status()
{
ifstream t("/proc/self/status");
cerr << string(istreambuf_iterator<char>(t), istreambuf_iterator<char>()) << endl;
} template<class T> inline T read()
{
register T x(0);
register char c;
register int f(1);
while (!isdigit(c = getchar())) if (c == '-') f = -1;
while (x = (x << 1) + (x << 3) + (c xor 48), isdigit(c = getchar()));
return x * f;
} template<typename T> inline bool chkmin(T &a, T b) { return a > b ? a = b, 1 : 0; }
template<typename T> inline bool chkmax(T &a, T b) { return a < b ? a = b, 1 : 0; } const int maxN = 4e5;
const int maxM = 20; int n;
vector<int> col[maxM + 1];
LL cnt[maxM + 1][maxM + 1];
LL dp[1 << maxM]; void Input()
{
n = read<int>();
for (int i = 1; i <= n; ++i)
{
int x = read<int>();
col[x].push_back(i);
}
} void Init()
{
for (int i = 1; i <= 20; ++i)
for (int j = 1; j <= 20; ++j)
if (i != j)
{
if (!col[i].size() || !col[j].size()) continue;
int l = 0;
for (int k = 0; k < SZ(col[i]); ++k)
{
while (true)
{
if (l == SZ(col[j]) - 1 || col[j][l + 1] > col[i][k])
break;
l++;
}
if (col[j][l] < col[i][k])
cnt[i][j] += l + 1;
}
}
} void Solve()
{
memset(dp, 0x3f, sizeof dp); dp[0] = 0;
for (int S = 0; S < 1 << maxM; ++S)
{
for (int i = 0; i < maxM; ++i)
if (!(S >> i & 1))
{
LL sum(0);
for (int j = 0; j < maxM; ++j)
if (S >> j & 1)
sum += cnt[j + 1][i + 1];
chkmin(dp[S | (1 << i)], dp[S] + sum);
}
} cout << dp[(1 << maxM) - 1] << endl;
} int main()
{
#ifndef ONLINE_JUDGE
freopen("CF585E.in", "r", stdin);
freopen("CF585E.out", "w", stdout);
#endif
Input();
Init();
Solve();
return 0;
}

[CF585E]Marbles的更多相关文章

  1. Marbles启动信息

    body-parser deprecated undefined extended: provide extended option app.js:40:20 -------------------- ...

  2. UVA 10090 - Marbles 拓展欧几里得

    I have some (say, n) marbles (small glass balls) and I am going to buy some boxes to store them. The ...

  3. Codeforces Round #336 Marbles

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

  4. uva 10090 Marbles

    Problem F Marbles Input: standard input Output: standard output I have some (say, n) marbles (small ...

  5. UVA11125 - Arrange Some Marbles(dp)

    UVA11125 - Arrange Some Marbles(dp) option=com_onlinejudge&Itemid=8&category=24&page=sho ...

  6. CF585E. Present for Vitalik the Philatelist [容斥原理 !]

    CF585E. Present for Vitalik the Philatelist 题意:\(n \le 5*10^5\) 数列 \(2 \le a_i \le 10^7\),对于每个数\(a\) ...

  7. 基于ubuntu16.04部署IBM开源区块链项目-弹珠资产管理(Marbles)

    前言 本教程基本上是对Marbles项目的翻译过程. 如果英文比较好的话,建议根据官方操作说明,一步步进行环境部署.当然你也可以参考本教程在自己的主机上部署该项目. Marbles 介绍 关于 Mar ...

  8. UVA 10090 Marbles(扩展欧几里得)

    Marbles Input: standard input Output: standard output I have some (say, n) marbles (small glass ball ...

  9. 【AtCoder】ARC086 E - Smuggling Marbles

    [题目]E - Smuggling Marbles [题意]给定n+1个点的树(root=0),每个点可以选择放或不放弹珠,每一轮顺序进行以下操作: 1.将根节点0的弹珠加入答案. 2.每个点的弹珠移 ...

随机推荐

  1. 两句话掌握 Python 最难知识点——元类

    千万不要被所谓“元类是99%的python程序员不会用到的特性”这类的说辞吓住.因为每个中国人,都是天生的元类使用者 学懂元类,你只需要知道两句话: 道生一,一生二,二生三,三生万物 我是谁?我从哪来 ...

  2. 各种注意事项(还有c++的一些操作)

    转c++时间: 2017年8月9号 1.记得打头文件 2.=与==的区别(赋值|比较) 3.各种运算符的比较级(与Pascal不同),主要是==与位运算 *4.在OJ上scanf和printf时间优于 ...

  3. UOJ #395 BZOJ 5417 Luogu P4770 [NOI2018]你的名字 (后缀自动机、线段树合并)

    NOI2019考前做NOI2018题.. 题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=5417 (luogu) http ...

  4. Spring Cloud Stream教程(四)消费群体

    虽然发布订阅模型可以轻松地通过共享主题连接应用程序,但通过创建给定应用程序的多个实例来扩展的能力同样重要.当这样做时,应用程序的不同实例被放置在竞争的消费者关系中,其中只有一个实例预期处理给定消息. ...

  5. 初识REST

    RESTful介绍: REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移”或“表现层状态转化”. 1 ...

  6. 《Effective Java》读书笔记 - 10.并发

    Chapter 10 Concurrency Item 66: Synchronize access to shared mutable data synchronized这个关键字不仅保证了同步,还 ...

  7. express 请求参数的一些问题

    先说点别的,项目入口是index.js,运行 node index 启动项目. 路由部分app.get('/', function(req, res) { res.send('hello, expre ...

  8. Mysql锁表问题解决过程

    开发中难免会遇到数据库操作锁表问题,这里说下解决过程,算是记录了. show OPEN TABLES where In_use > 0; 查看哪些表被锁了 show processlist 查看 ...

  9. a标签点击,页面自动刷新

    <a href="javascript:void(0)" id="reDiagnosis" class="checkBtn"oncli ...

  10. angular 的配置文件的应用

    为什么要使用 angular 的配置文件: 好处:我们可以在一个页面上,实现多个页面的跳转的感觉,但只是在一个页面上进行的操作: 我们的准备工作:下载 angular-route.js 插件 在依赖模 ...