Valera and Swaps
题意:
定义 $f(p)$ 表示将 $p$ 序列变换为有序序列最少要交换多少次,给一 $1 \sim n$ 的排列 $a$ ,给一整数 $m$,
求问将 $a$ 最少交换多少次能得到 $p$ ,使得 $f(p) = m$,并将以此交换视作一个两个数字,将交换按顺序排列开
求出字典序最小的交换序列。
解法:
记 $id$ 表示排列 $id(i) = i$
考虑 $f(p)$ 怎么求,可以发现,将原排列视作一个从$p$置换到$id$的置换,则将置换拆分成 $tot$ 个循环后,
最小交换次数就是$\sum_{i=1}^{tot}{cnt_i - 1}$,也就是$n - tot$。
这样考虑交换两个置换的元素,两个置换群会合为一个置换群, $tot$ 变为 $tot-1$。
考虑交换一个置换群内的元素,当前置换群会拆分为两个置换群,$tot$ 变为 $tot+1$。
我们注意到要求交换次数最小,这样两种操作一定不会共存,
这样分类讨论:
1.$n-m < tot$时,我们需要将原先的置换群不断合并,要求字典序最小,
所以我们每次找出含最小元素的置换,将其与含1的置换合并。
2.$n-m = tot$时,不用交换,答案为0
3.$n-m > tot$时,每一次我们只要选择含最小元素的置换,将其中的最小值和次小值交换,并将置换拆开。
总复杂度$O(n^2)$
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector> #define N 3010
#define LL long long using namespace std; int n,m,tot;
int a[N];
bool v[N];
vector<int> cir[N]; int main()
{
while(~scanf("%d",&n))
{
for(int i=;i<=n;i++) scanf("%d",&a[i]);
scanf("%d",&m);
m=n-m;
for(int i=;i<=n;i++) v[i]=;
tot=;
for(int i=;i<=n;i++)
{
if(v[i]) continue;
int tmp=i;
cir[++tot].clear();
while(!v[tmp])
{
v[tmp]=;
cir[tot].push_back(tmp);
tmp=a[tmp];
}
}
if(tot==m) cout<<<<endl;
else if(tot>m)
{
cout<<tot-m<<endl;
for(int Te=;Te<=tot-m;Te++)
{
int t=;
for(int i=;i<=tot;i++)
if(!cir[i].empty() && (!t || cir[i][]<cir[t][]))
t=i;
cout<<cir[][]<<' '<<cir[t][]<<' ';
for(int i=;i<(int)cir[t].size();i++)
cir[].push_back(cir[t][i]);
cir[t].clear();
}
}
else
{
int tott=tot;
cout<<m-tot<<endl;
for(int Te=;Te<=m-tot;Te++)
{
int t=;
for(int i=;i<=tott;i++)
if(cir[i].size()> && (!t || cir[i][]<cir[t][]))
t=i;
int pos=;
for(int i=;i<(int)cir[t].size();i++)
if(cir[t][i]<cir[t][pos])
pos=i;
cout<<cir[t][]<<' '<<cir[t][pos]<<' ';
swap(cir[t][],cir[t][pos]);
cir[++tott].clear();
int cnt=;
for(int i=pos;i<(int)cir[t].size();i++)
cir[tott].push_back(cir[t][i]),cnt++;
while(cnt--) cir[t].pop_back();
}
}
}
return ;
}
Valera and Swaps的更多相关文章
- CodeForces - 441D: Valera and Swaps(置换群)
A permutation p of length n is a sequence of distinct integers p1, p2, ..., pn (1 ≤ pi ≤ n). A permu ...
- Codeforces 441D Valera and Swaps(置换群)
题意: 给定一个1~n的排列(n<=3000),输出字典序最小且次数最少的交换操作,使得操作后的排列可以通过最少m次交换得到排列[1,2,...n] Solution: 可以将排列的对应关系看做 ...
- CF(441D Valera and Swaps)置换群
题意:1-n的一个排列, p2, ..., pn,f(p)的定义是此排列要交换最少的数对能够回到原排列1,2,3,4...n.给一个排列p.要将其变换成f值为m的排列,问至少要交换几个数对,并输出字典 ...
- Codeforces Round 252 (Div. 2)
layout: post title: Codeforces Round 252 (Div. 2) author: "luowentaoaa" catalog: true tags ...
- [codeforces 339]E. Three Swaps
[codeforces 339]E. Three Swaps 试题描述 Xenia the horse breeder has n (n > 1) horses that stand in a ...
- CF 369C . Valera and Elections tree dfs 好题
C. Valera and Elections The city Valera lives in is going to hold elections to the city Parliament ...
- uva331 - Mapping the Swaps
Mapping the Swaps Sorting an array can be done by swapping certain pairs of adjacent entries in the ...
- UVA Mapping the Swaps
题目例如以下: Mapping the Swaps Sorting an array can be done by swapping certain pairs of adjacent entrie ...
- [Codeforces Round #237 (Div. 2)] A. Valera and X
A. Valera and X time limit per test 1 second memory limit per test 256 megabytes input standard inpu ...
随机推荐
- inch mil mm换算
inch:英寸 mil:密耳 mm:毫米 1mil=0.0254mm=25.4um 1mm=39.37mil 1inch=1000mil=25.4mm
- PCB板布线中地线和电源线的布线规则
电源. 地线的布置考虑不周到而引起干扰,使产品的性能下降,严重时会降低产品的成功率.要把电源线和地线处理好,将电源线和地线所产生的噪音干扰降到最低限度,以保证产品的质量.一.电源线和地线的布线规则1) ...
- kubernetes里的各种port解惑
系列目录 在编排kubernetes时,Deployment的Pod项有containerPort,Service文件里的port,targetPort, nodePort,这些pod概念有些时候可能 ...
- 在jquery的ajax方法中的success中使用return要注意的问题
jquery的ajax方法:在success中使用return:来结束程序的时候,结束的只是success这个方法,也就是说success中的return的作用范围只是success: 如果要想在su ...
- 使用 fcntl 函数 获取,设置文件的状态标志
前言 当打开一个文件的时候,我们需要指定打开文件的模式( 只读,只写等 ).那么在程序中如何获取,修改这个文件的状态标志呢?本文将告诉你如何用 fcntl函数 获取指定文件的状态标志. 解决思路 1. ...
- 开源安卓Android流媒体音视频播放器实现声音自动停止、恢复、一键静音功能源码
本文转自EasyDarwin团队John的博客:http://blog.csdn.net/jyt0551/article/details/60802145 我们在开发安卓Android流媒体音视频播放 ...
- mongoose在Windows Server 2003上不能访问问题的解决
这两天在部署EasyDarwin开源流媒体服务器到Windows Server 2003的时候,奇怪地发现,在Windows 2003上面,mongoose的web管理端口居然无法访问,但通过nets ...
- 创建私有maven库
在公司搭建私有maven库,我为了在本机做测试,我选择Sonatype nexus oss,在docker里面安装 1.Mac上安装docker 下载地址:https://github.com/boo ...
- PHP开发工作心得
一.扎实PHP自身的基础知识.函数.常量等,尽量用内置的方法解决这个问题(由于个人写的往往运行效率没有内置方法高): 二.代码尽量少的实现功能(由于PHP的运行事实上是,将咱们的代码先处理成底层语言进 ...
- Impala 安装笔记1一Cloudera CDH4.3.0安装
Impala是Cloudera在受到Google的Dremel启发下开发的实时交互SQL大数据查询工具,Impala没有再使用缓慢的Hive+MapReduce批处理,而是通过使用与商用并行关系数据库 ...