首页 > 其他分享 >Marbles 题解

Marbles 题解

时间:2024-09-05 08:52:53浏览次数:4  
标签:颜色 Marbles int 题解 交换 setminus 序列 逆序

前言

题目链接:Codeforces洛谷

题意简述

给定长度为 \(n\) 的序列 \(a\),你可以交换相邻元素,请问最少交换多少次使得序列连续,即对于每种颜色,其在序列中出现的位置都是连续一段。

\(m = \max \{ a_i \} \leq 20\),\(n \leq 4 \times 10 ^ 5\)。

题目分析

对于“连续的序列”,不放看做我们给每种颜色钦定了一个优先级,然后按照优先级排了一个序。想到一个定理,将一个序列排序最少交换相邻元素的次数等于该序列的逆序对数。证明很简单,考虑冒泡排序的过程,我们每次交换相邻的逆序对,能够减少一对逆序对,而逆序对为 \(0\) 的时候,序列有序。由于每次操作做多使逆序对减少 \(1\),所以操作次数至少是逆序对个数,而我们有证明了按照冒泡排序的方式,一定存在一种方式达到这个下限,所以得证。

看到数据范围,很容易想到状压 DP。记 \(f_{S}\) 表示只考虑集合 \(S\) 中的颜色,使得其连续的最小交换次数。最后答案就是 \(f_{\{i\}_{i = 1}^m}\)。边界 \(f_{\varnothing} = 0\)。

考虑由 \(f_{S \setminus \{ x \}}\) 转移到 \(f_{S}\)。此时 \(x\) 为 \(S\) 中我们钦定优先级最大的颜色,即我们需要让所有颜色为 \(x\) 的数交换到 \(S \setminus \{x \}\) 的右边。对于每一个 \(a_i = x\) 的 \(i\),交换它的次数等于它的逆序对数,即有多少个 \(a_j \in S \setminus \{ x \} \land j > i\)。这个预处理 \(w_{u, v}\) 表示为了让颜色 \(u\) 全部到 \(v\) 的右边的交换次数即可。那么转移即为 \(f_{S} = \min \Big \{ f_{S \setminus \{x\}} + \sum \limits _{y\in S \setminus \{x\}} w_{x, y} \Big\}\)。

时间复杂度 \(\Theta(m 3^m + nm)\),可以预处理优化掉转移的 \(\sum\),时间复杂度:\(\Theta(m 2^m + 3^m + nm)\)。

代码

#include <cstdio>
#include <iostream>
using namespace std;

const int N = 400010;
const int K = 20;

int n, k = 20, val[N];
int cnt[K], p[1 << K];
long long yzh[K][1 << K], dp[1 << K];

inline int lowbit(int x) {
    return x & -x;
}

signed main() {
	scanf("%d", &n);
	for (int i = 1; i <= n; ++i) {
		scanf("%d", &val[i]), --val[i];
		++cnt[val[i]];
		for (int j = 0; j < k; ++j)
			yzh[j][1 << val[i]] += cnt[j];
	}
    for (int i = 0; i < k; ++i) {
        p[1 << i] = i;
        for (int st = 1; st < 1 << k; ++st)
            yzh[i][st] = yzh[i][st ^ lowbit(st)] + yzh[i][lowbit(st)];
    }
	for (int st = 1; st < 1 << k; ++st) {
		dp[st] = 0x3f3f3f3f3f3f3f3f;
        for (int S = st; S; S &= S - 1) {
            int i = lowbit(S);
            dp[st] = min(dp[st], dp[st ^ i] + yzh[p[i]][st ^ i]);
        }
	}
	printf("%lld", dp[(1 << k) - 1]);
	return 0;
}

标签:颜色,Marbles,int,题解,交换,setminus,序列,逆序
From: https://www.cnblogs.com/XuYueming/p/18397622

相关文章

  • [POI2014] RAJ-Rally 题解
    前言题目链接:Hydro&bzoj;黑暗爆炸;洛谷。题意简述DAG求删点后最长路的最小值。\(n\leq5\times10^5\),\(m\leq10^6\)。题目分析其实对于删点/边加查询最长/短路的套路是有的。比如:故乡的梦、桥。本题也类似。我们考虑,如果删除的边不在原来最长路上,那么删之后的......
  • CF1941场题解
    RudolfandtheTicket算法:枚举。题意简述:从\(a\)数组中和\(b\)数组中各选出一个数,使得它们的和不超过\(k\),求选法数量。考虑直接枚举每一种可能的搭配即可。Rudolfand121算法:贪心。题意简述:定义一次操作为,该位置上的数减去\(2\),其前一个和后一个位置(必须存在)上的数......
  • 2023 ICPC 合肥题解
    gymD.BalancedArray\(\star\)赛时做法枚举前缀维护合法的\(k\)感性上\(k\)越大需要满足的式子越少,只保留最大的\(\log\)个\(k\),可以通过std枚举\(k\),合法的\(l\)一定是一个左端点为\(2k+1\)的区间,二分右端点等式\(\forall1\lei\lel-2k,a_{i}+a_{i+2k}=2a......
  • Codeforces Round 971 (Div. 4) ABCD题详细题解(C++,Python)
    前言:    本文为CodeforcesRound971(Div.4)ABCD题的题解,包含C++,Python语言描述,觉得有帮助或者写的不错可以点个赞    比赛打了没一半突然unrated了就不是很想继续写了,早起写个题解    (之前的div3也没复盘,哎真菜)目录题A:题目大意和解题......
  • AtCoder Beginner Contest 369 题ABCD详细题解--包含解题思路和两种语言(C++,Python)
    前言:    本文为AtCoderBeginnerContest369题ABCD详细题解,包括题目大意,详细的解题思路和两种语言描述,觉的有帮助或者写的不错可以点个赞几天前的比赛拖的有点久了比赛题目连接:Tasks-AtCoderBeginnerContest369目录题A:题目大意和解题思路:代码(C++):......
  • 洛谷 B3645 数列前缀和 2 题解
    前缀知识:枚举,费马小定理,逆元,线性乘法逆元,线段树(?)。解法1:暴力如题。暴力枚举即可,30分。由于太简单,不给代码。解法2:前缀积+费马小定理+逆元由于涉及静态区间,可以想到前缀积。前缀积公式为\(q_r/q_{l-1}\),除法恰好可以用逆元来算。直接写即可。不会超时,因为时间为\(O(n\logp)\)......
  • Codeforces Round 971 (Div. 4) E 题解析
    #E题Klee'sSUPERDUPERLARGEArray!!!题目描述思路:对于这道题,首先观察到题目求的是最小可能值,而且数据的范围是1e9范围,所以首先可以考虑的方法就是O(logn)的方法,而适合求最值的方法无疑就是二分搜索,可以通过二分来不断缩小答案的区间......
  • 常见问题解决 --- 如何给一个不支持配置代理的程序抓取https流量数据
    比如我有一个C#编写票务系统,它内嵌浏览器功能,我想抓取它的流量,但是这个客户端不支持配置代理设置解决办法:1.安装配置proxifier开启全局代理服务。安装好后网上有激活码激活一下,点击profile-proxyserver,添加一个代理服务器127.0.0.1,端口8080,协议https。点击profile-proxifi......
  • 历年CSP-J初赛真题解析 | 2017年CSP-J初赛阅读程序(23-26)
    学习C++从娃娃抓起!记录下CSP-J备考学习过程中的题目,记录每一个瞬间。附上汇总贴:历年CSP-J初赛真题解析|汇总_热爱编程的通信人的博客-CSDN博客#include<iostream>usingnamespacestd;intmain(){ intt[256]; strings; inti; cin>>s; for(i=0;i<256;i......
  • 2024年“羊城杯”粤港澳大湾区网络安全大赛 初赛 Web&数据安全&AI 题解WriteUp
    文章首发于【先知社区】:https://xz.aliyun.com/t/15442LyricsForYou题目描述:Ihavewrotesomelyricsforyou…开题。看一下前端源码,猜测有路径穿越漏洞http://139.155.126.78:35502/lyrics?lyrics=../../../../../etc/passwd简单看一下环境变量,没有flag。扫......