BZOJ 2058 [Usaco2010 Nov]Cow Photographs:逆序对【环上最小逆序对】
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2058
题意:
给你一个由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:
#include <iostream>
#include <stdio.h>
#include <string.h>
#define MAX_N 100005
#define INF 1000000000 using namespace std; int n;
int a[MAX_N];
int l[MAX_N];
int r[MAX_N];
int dat[MAX_N];
int pos[MAX_N];
long long ans=;
long long res=; void read()
{
cin>>n;
for(int i=;i<=n;i++)
{
cin>>a[i];
pos[a[i]]=i;
}
} void merge(int lef,int mid,int rig)
{
int n1=mid-lef+;
int n2=rig-mid;
for(int i=;i<n1;i++) l[i]=a[lef+i];
for(int i=;i<n2;i++) r[i]=a[mid+i+];
l[n1]=INF;
r[n2]=INF;
for(int i=,j=,k=lef;k<=rig;k++)
{
if(l[i]<r[j]) a[k]=l[i++];
else
{
a[k]=r[j++];
res+=n1-i;
}
}
} void merge_sort(int lef,int rig)
{
if(lef==rig) return;
int mid=(lef+rig)/;
merge_sort(lef,mid);
merge_sort(mid+,rig);
merge(lef,mid,rig);
} void solve()
{
merge_sort(,n);
ans=res;
for(int i=;i<n;i++)
{
res=res-*pos[i]++n;
ans=min(ans,res);
}
} void print()
{
cout<<ans<<endl;
} int main()
{
read();
solve();
print();
}
BZOJ 2058 [Usaco2010 Nov]Cow Photographs:逆序对【环上最小逆序对】的更多相关文章
- Bzoj 2058: [Usaco2010 Nov]Cow Photographs 题解
2058: [Usaco2010 Nov]Cow Photographs Time Limit: 3 Sec Memory Limit: 64 MBSubmit: 190 Solved: 104[ ...
- bzoj2058: [Usaco2010 Nov]Cow Photographs(逆序对)
题目大意:给出n个数的序列,每次可以交换相邻的两个数,问把序列变成编号i在编号i+1左边,编号1在编号n右边(一个环)最少需要多少步.如:35421最少交换两次变为34512. 一开始看到这题,只会O ...
- BZOJ_2058_[Usaco2010 Nov]Cow Photographs_逆序对
BZOJ_2058_[Usaco2010 Nov]Cow Photographs_逆序对 题意: 奶牛的图片 Farmer John希望给他的N(1<=N<=100,000)只奶牛拍照片, ...
- [bzoj2058][Usaco2010 Nov]Cow Photographs_树状数组_动态规划
Cow Photographs bzoj-2058 Usaco-2010 Nov 题目大意:给定一个n的排列.每次操作可以交换相邻两个数.问将序列变成一个:$i,i+1,i+2,...,n,1,2,. ...
- BZOJ 2060: [Usaco2010 Nov]Visiting Cows 拜访奶牛( dp )
树形dp..水 ------------------------------------------------------------------------ #include<cstdio& ...
- BZOJ 1641: [Usaco2007 Nov]Cow Hurdles 奶牛跨栏( floyd )
直接floyd.. ---------------------------------------------------------------------------- #include<c ...
- BZOJ 1629 [Usaco2005 Nov]Cow Acrobats:贪心【局部证明】
题目链接:http://begin.lydsy.com/JudgeOnline/problem.php?id=1332 题意: 有n头牛在“叠罗汉”. 第i头牛的体重为w[i],力量为s[i]. 一头 ...
- BZOJ 1641: [Usaco2007 Nov]Cow Hurdles 奶牛跨栏
Description Farmer John 想让她的奶牛准备郡级跳跃比赛,贝茜和她的伙伴们正在练习跨栏.她们很累,所以她们想消耗最少的能量来跨栏. 显然,对于一头奶牛跳过几个矮栏是很容易的,但是高 ...
- BZOJ 1641 [Usaco2007 Nov]Cow Hurdles 奶牛跨栏:新版floyd【路径上最大边最小】
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1641 题意: 给你一个有向图,n个点(n <= 300),m条边,边权为h[i]. ...
随机推荐
- 【数据挖掘】分类之kNN(转载)
[数据挖掘]分类之kNN 1.算法简介 kNN的思想很简单:计算待分类的数据点与训练集所有样本点,取距离最近的k个样本:统计这k个样本的类别数量:根据多数表决方案,取数量最多的那一类作为待测样本的类别 ...
- shiro自定义拦截url
在实际项目上,我们针对不同的用户(guste,user,admin,mobile user)等等,需要进入不同的页面,比如,手机端用户需要进入Mobile/这个路径下的,这个时候,我们需要自定义拦截u ...
- 文本信息检索——布尔模型和TF-IDF模型
文本信息检索--布尔模型和TF-IDF模型 1. 布尔模型 如要检索"布尔检索"或"概率检索"但不包括"向量检索"方面的文档,其相应的查 ...
- 向MapReduce转换:通过部分成绩计算矩阵乘法
代码共分为四部分: <strong><span style="font-size:18px;">/*** * @author YangXin * @info ...
- Android调用相机实现拍照并裁剪图片,调用手机中的相冊图片并裁剪图片
在 Android应用中,非常多时候我们须要实现上传图片,或者直接调用手机上的拍照功能拍照处理然后直接显示并上传功能,以下将讲述调用相机拍照处理图片然后显示和调用手机相冊中的图片处理然后显示的功能,要 ...
- [root@localhost ~]#各项解释
[root@localhost ~]# 解释: [登录用户@主机名 索引目录(~家目录,当前所在的目录)]#号代表超级用户,$普通用户
- python基础-------python2.7教程学习【廖雪峰版】(二)
2017年6月7日14:59:27任务: 看完python基础1.计算机顾名思义就是可以做数学计算的机器,因此,计算机程序理所当然地可以处理各种数值.但是,计算机能处理的远不止数值,还可以处理文 ...
- apache常用模块介绍
mod_actions 基于媒体类型或请求方法,为执行CGI脚本而提供 mod_alias 提供从文件系统的不同部分到文档树的映射和URL重定向 mod_asis 发送自己包含HTTP头内容的文件 ...
- Lorenzo Von Matterhorn(STL_map的应用)
Lorenzo Von Matterhorn time limit per test 1 second memory limit per test 256 megabytes input standa ...
- python学习-3.一些常用模块用法
一.time.datetime 时间戳转化为元组 1 >>> time.localtime() 2 time.struct_time(tm_year=2016, tm_mon=8, ...