noip2013火柴排队_Solution
要想对任意(ai,bi)和(aj和bj),当ai<aj时,都有bi<=bj;当ai>=aj时,bi>=bj,当对a进行升序排序后(b同时发生改变,从而不改变值,最后有a1<=a2<=…<=an),必须满足b1<=b2<=…<=bn。
否则,必存在(ai,bi)和(aj和bj),有ai<aj且bi>bj,交换ai和aj后,(aj*bi+ ai*bj)-( ai*bi+ aj*bj)=(aj-ai)*( bi-bj)>0,数值更小,即不是所满足的序列。
唯有满足条件“对任意(ai,bi)和(aj和bj),当ai<aj时,都有bi<=bj;当ai>=aj时,bi>=bj”的序列才是值最小的序列。
最后目的是:对任意(ai,bi)和(aj和bj),当ai<aj时,都有bi<=bj;当ai>=aj时,bi>=bj,其中题目限制“同一列火柴的高度互不相同”,所以对a,b序列进行从小到大排序,数的编号具有唯一性,即最后a,b两个序列中,ai在a序列的编号等于bi在b序列的编号。
每一次操作,一列(a,b数组)中相邻的两个数进行交换,其中ai和ai+1的交换等效于bi和bi+1的交换。我们可以固定a序列不动,修改b序列,最优的操作满足操作次数最少。
b序列第i位的数要移到目标位置第vi位中,求出v序列。b序列的数的移动顺序是按照对应的v序列的数从小到大。当目标位置为第vi位对应的bi(原来)需要移动时,前面的第1~vi-1位已经排好,而其它bi(原来)前面的数为还未移动的数,即对应的v序列的值大于vi。所以bi(原来)需要向左移动的次数为满足j<i and vj>vi所有的j的个数。
即总的操作次数为v序列的逆序对的个数。有两种方法求逆序对使得时间复杂度为O(nlogn):
1.归并排序+统计
2.离散化+树状数组
Code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define yu 99999997
#define maxn 100000
struct node
{
long value,pos;
}a[maxn+],b[maxn+];
long v[maxn+],t[maxn+],ans;
int cmp(const void *a,const void *b)
{
if ((*(struct node *)a).value<(*(struct node *)b).value)
return -;
else
return ;
}
void mergesort(long l,long r)
{
if (l==r)
return ;
long mid,x,y,z,i;
mid=(l+r)/;
mergesort(l,mid);
mergesort(mid+,r);
for (i=l;i<=r;i++)
t[i]=v[i];
x=l;
y=mid+;
z=l;
while (x<=mid && y<=r)
{
//两个数相等时让左边的数先加,因为相同的数不能凑成一对
if (t[x]<=t[y])
{
v[z]=t[x];
x++;
//v[x] > v[mid+1]~v[y-1]
ans=(ans+(y-mid-))%yu;
}
else if (t[x]>t[y])
{
v[z]=t[y];
y++;
}
z++;
}
if (x<=mid)
{
//v[x] > v[mid+1]~v[r]
ans=(ans+(mid-x+)*(r-mid))%yu;
while (z<=r)
{
v[z]=t[x];
x++;
z++;
}
}
else
{
while (z<=r)
{
v[z]=t[y];
y++;
z++;
}
}
}
int main()
{
long n,i;
scanf("%ld",&n);
for (i=;i<=n;i++)
{
scanf("%ld",&a[i].value);
a[i].pos=i;
}
for (i=;i<=n;i++)
{
scanf("%ld",&b[i].value);
b[i].pos=i;
}
qsort(a+,n,sizeof(struct node),cmp);
qsort(b+,n,sizeof(struct node),cmp);
for (i=;i<=n;i++)
v[b[i].pos]=a[i].pos;
ans=;
mergesort(,n);
printf("%ld\n",ans);
return ;
}
/*
Input:
10
10 1 5 2 7 4 9 3 6 8
7 5 1 8 10 4 6 2 3 9
Output:
18
*/
感慨一下:想当初比赛做这道题,没有想到是逆序对,最终没有做出来,留下遗憾。现在终于写了个题解,把这道题做了,算是对遗憾的一种弥补吧。
希望自己可以走得更远……
noip2013火柴排队_Solution的更多相关文章
- LOJ2609. NOIP2013 火柴排队 【树状数组】
LOJ2609. NOIP2013 火柴排队 LINK 题目大意: 给你两个数列,定义权值∑i=1(ai−bi)^2 问最少的操作次数,最小化权值 首先需要发现几个性质 最小权值满足任意i,j不存在a ...
- [树状数组+逆序对][NOIP2013]火柴排队
火柴排队 题目描述 涵涵有两盒火柴,每盒装有n根火柴,每根火柴都有一个高度.现在将每盒中的火柴各自排成一列,同一列火柴的高度互不相同,两列火柴之间的距离定义为:∑ (ai-bi)2,i=1,2,3,. ...
- NOIP2013火柴排队[逆序对]
题目描述 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: ∑(ai-bi)^2 其中 ai 表示 ...
- [NOIP2013] 火柴排队(归并排序)
题目描述 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: ∑(ai-bi)^2 其中 ai 表示 ...
- noip2013 火柴排队
题目描述 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高度. 现在将每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 两列火柴之间的距离定义为: ∑(ai-bi)^2 其中 ai 表示 ...
- jzoj[1438]NOIP2013火柴排队
读题: 相邻两个火柴可以交换?两个火柴序列?嗅到了归并排序的味道. 读完题目之后,我们可以知道,如果想要交换次数最少,可以先固定一个序列不变,比如说a序列不变,变b序列 样例是 4 2 3 1 4 3 ...
- NOIP2013火柴排队
Solution 恕我直言,这题是真的坑. 对于这道题,一个很显然的思路是对于A B两个序列,他们交换完后相对的两个数在原序列中的相对大小是相同的,于是我们就把序列按照A排序,在把B离散化,求逆序对, ...
- NOIp2013 火柴排队【逆序对/思维】 By cellur925
题目大意:给你两列数\(ai\)和\(bi\),你可以交换每列数中相邻的两个数,求一个最小交换次数使\(\sum_{i=1}^{n}(a_i-b_i)^2\) 最小. 最后满足条件的两个序列一定是各个 ...
- NOIP 2013 火柴排队
洛谷 P1966 火柴排队 洛谷传送门 JDOJ 2227: [NOIP2013]火柴排队 D1 T2 JDOJ传送门 Description 涵涵有两盒火柴,每盒装有 n 根火柴,每根火柴都有一个高 ...
随机推荐
- Python - 列表解析式
列表解析——用来动态地创建列表 [expr for iter_var in iterable if cond_expr] 例子一: map(lambda x: x**2, range(6)) [0, ...
- python报错问题解决:'ascii' codec can't encode character
之前部署了openstack虚拟化环境,有一天在使用nova list查看虚拟机的时候,突然报错!如下: [root@linux-node1 src]# nova listERROR (Unicode ...
- snmpd.conf 配置
开启snmp后,一些指标获取不到,需要配置snmpd.conf文件,如下图所示 参考文章:http://blog.csdn.net/flyingfalcon/article/details/47831 ...
- php 中 opendir() readdir() scandir()
opendir(path,context)若成功,则该函数返回一个目录流,否则返回 false 以及一个 error.可以通过在函数名前加上 “@” 来隐藏 error 的输出. readdir() ...
- Dubbo原理和源码解析之服务暴露
github新增仓库 "dubbo-read"(点此查看),集合所有<Dubbo原理和源码解析>系列文章,后续将继续补充该系列,同时将针对Dubbo所做的功能扩展也进行 ...
- vs感受,由于我的电脑装了俩年了!我直接写感受吧
个人感受:最初的感觉,最开始装vs是因为我的电脑8.1不兼容vc6.0(一个挺坑的编程软件),最开始用vs的时候我还是一个小白什么都不懂,vs创建项目实在是太复杂,不看教程根本看不懂,也许是它能包容的 ...
- “北航学堂”M2阶段postmortem
“北航学堂”M2阶段postmortem 设想和目标 1. 我们的软件要解决什么问题?是否定义得很清楚?是否对典型用户和典型场景有清晰的描述? 这个问题我们在M1阶段的时候就已经探讨的比较明确了,就是 ...
- M2 终审
1.团队成员简介 左边:马腾跃 右边:陈谋 左上:李剑锋 左下:仉伯龙 右:卢惠明 团队成员及博客: 李剑锋: Blog: http://www.cnblogs.com/Po ...
- win10装MySQL5.7
越来越发现装MySQL很费劲啊,装了N次,都很懵逼,找对的解决方案很重要. Mysql5.7下载地址:http://xiazai.zol.com.cn/detail/4/33431.shtml 安装步 ...
- java注解的简单介绍
什么是注解 1.注解就是Annontation,Annontation是Java5开始引入的新特征,中文名称叫做注解,它提供了一种安全的类似注释的机制,可以起到减少配置的成果,给程序起到辅助性的作用 ...