博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
BZOJ 2058 [Usaco2010 Nov]Cow Photographs:逆序对【环上最小逆序对】
阅读量:5367 次
发布时间:2019-06-15

本文共 1184 字,大约阅读时间需要 3 分钟。

题目链接:

题意:

  给你一个由1~n组成的排列,首尾相接围成一个环。

  你可以任意次交换其中两个相邻位置的数字。

  最终你要让所有数字顺时针递增,只有n顺时针紧邻着1。

  问你最小的交换次数。

 

题解:

  举个例子。

  有一个由1~5组成的环:2 3 1 4 5

  对于这个环,最终答案有若干种情况:

    (1)1 2 3 4 5

    (2)2 3 4 5 1

    (3)3 4 5 1 2

    (4)4 5 1 2 3

    (5)5 1 2 3 4

  每一次变化,无非是分别将1~4移到了最右边。

  对于从(1)到(2)的变化,其实就是将原环中的1改为了一个比其他都大的数字(比如6),然后求了一遍逆序对。

  对应到最终结果中,也就是1变成了最右边的数。

 

  所以变化之后的答案 = 上一次的答案 - 数字i所贡献的逆序对个数 + 改成的更大的数所贡献的逆序对个数

 

  对于每一次将数字i改为更大的数时,i一定是当前环中最小的数字。

  令pos[i]为数字i在原环中出现的位置(1 <= pos <= n)。

  所以:

    i贡献的逆序对 = pos[i] - 1

    更大的数贡献的逆序对 = n - pos[i]

  即:res = res - 2*pos[i] + 1 + n

  

  对于所有res取最小即可。

 

AC Code:

1 #include 
2 #include
3 #include
4 #define MAX_N 100005 5 #define INF 1000000000 6 7 using namespace std; 8 9 int n;10 int a[MAX_N];11 int l[MAX_N];12 int r[MAX_N];13 int dat[MAX_N];14 int pos[MAX_N];15 long long ans=0;16 long long res=0;17 18 void read()19 {20 cin>>n;21 for(int i=1;i<=n;i++)22 {23 cin>>a[i];24 pos[a[i]]=i;25 }26 }27 28 void merge(int lef,int mid,int rig)29 {30 int n1=mid-lef+1;31 int n2=rig-mid;32 for(int i=0;i

 

转载于:https://www.cnblogs.com/Leohh/p/7704438.html

你可能感兴趣的文章
lambda----jdk8重头戏
查看>>
Java容器——Map接口
查看>>
python 2.7 rsa 离线安装 和使用示例
查看>>
module.exports与exports,export与export default之间的关系和区别
查看>>
菜单小谈
查看>>
Python第三方模块tesserocr安装
查看>>
【Gamma】Scrum Meeting 7
查看>>
Android SQlite详解
查看>>
BBS-项目流程分析-表的创建
查看>>
操作系统简介
查看>>
创建一个dynamics CRM workflow (五) - Deploy Custom Workflows
查看>>
ThinkPHP - Widget 工具
查看>>
前端图片上传预览
查看>>
(ZZ)ACM之歌
查看>>
Mecanim高级主题:Mecanim Blend Tree应用、Blend Tree 选项、复合Blend Tree
查看>>
分页/pagination
查看>>
HOJ Funfair
查看>>
web前端使用localstorage、sessionstorage、cookie增删获方法
查看>>
不要轻视行动的力量
查看>>
Python中re的match、search、findall、finditer区别
查看>>