【t099】最接近神的人
Time Limit: 1 second
Memory Limit: 128 MB
【问题描述】
破解了符文之语,小FF开启了通往地下的道路。当他走到最底层时,发现正前方有一扇巨石门,门上雕刻着一幅古代人进行某种活
动的图案。而石门上方用古代文写着“神的殿堂”。小FF猜想里面应该就有王室的遗产了。但现在的问题是如何打开这扇门…
… 仔细研究后,他发现门上的图案大概是说:古代人认为只有智者才是最容易接近神明的。
而最聪明的人往往通过一种仪式选拔出来。仪式大概是指,即将隐退的智者为他的候选人写下一串无序的数字,并让他们进行一种
操作,即交换序列中相邻的两个元素。而用最少的交换次数使原序列变成不下降序列的人即是下一任智者。
小FF发现门上同样有着n个数字。于是他认为打开这扇门的秘诀就是找到让这个序列变成不下降序列所需要的最小次数。但小FF
不会……只好又找到了你,并答应事成之后与你三七分……
样例说明:开始序列为2 8 0 3,目标序列为0 2 3 8,可进行三次操作的目标序列:
1. Swap(8,0):2 0 8 3
2. Swap (2,0):0 2 8 3
3. Swap (8,3):0 2 3 8
【数据范围】
对于30%的数据1≤n≤104。
对于100%的数据 1≤n≤5*10
【输入格式】
第一行为一个整数n,表示序列长度
第二行为n个整数,表示序列中每个元素。
【输出格式】
一个整数ans,即最少操作次数。
Sample Input
4
2 8 0 3
Sample Output
3
【题目链接】:http://noi.qz5z.com/viewtask.asp?id=t099
【题解】
把n个数字变成有序;(只能交换相邻的数字);
考虑n个数字中最大的位置(最后要换到最后一个位置);
肯定是一个一个往后换(因为是最大的,所以就是它后面的逆序对个数比它小却在它后面的数字的个数);
然后把那个数字剔除掉(变成n-1个数字);
在这n-1个数字里面再找一个最大的(重复上述过程);
这个时候原来那个最大的数字已经去掉了;
所以这个原本第二大的元素(现在变成最大的了);
它也要放在第n-1个位置;
则它需要往后交换的次数也是它的逆序对个数(那个最大的数肯定不在它的逆序对里面,因为如果是最大的,那它不可能满足在它后面且比它小这个条件->现在你是第二大的!);
因为我们在做上面这个事情的过程中,不断把最大的数字返回到它应有的位置,而那些不该在那么后面的元素也被相应的交换到了前面(所以咱们没有做任何一件无意义的事情;所以我们得到的是最优解,渣渣只能这样骗自己了);
给个例子
在4个数中找最大的
4 9 5 2
9先移->9的逆序数为2;
4 5 2 9
然后不看9了;
在前3个数字中找最大的
5的逆序数为1;
4 2 5 9
….
就算9在5的后面,5的逆序数也是1!
逆序对用归并排序搞就好;
再给个线段树的链接http://blog.csdn.net/harlow_cheng/article/details/52453361
【完整代码】
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <set>
#include <map>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <string>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second
typedef pair<int,int> pii;
typedef pair<LL,LL> pll;
void rel(LL &r)
{
r = 0;
char t = getchar();
while (!isdigit(t) && t!='-') t = getchar();
LL sign = 1;
if (t == '-')sign = -1;
while (!isdigit(t)) t = getchar();
while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
r = r*sign;
}
void rei(int &r)
{
r = 0;
char t = getchar();
while (!isdigit(t)&&t!='-') t = getchar();
int sign = 1;
if (t == '-')sign = -1;
while (!isdigit(t)) t = getchar();
while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
r = r*sign;
}
const int MAXN = 5*10e5+100;
const int dx[5] = {0,1,-1,0,0};
const int dy[5] = {0,0,0,-1,1};
const double pi = acos(-1.0);
int n;
LL ans = 0,a[MAXN],temp[MAXN];
void mergesort(int l,int r)
{
if (l==r) return;
int m = (l+r)>>1;
mergesort(l,m);mergesort(m+1,r);
int i = l,j = m+1,k = i;
while (i <= m && j <= r)
if (a[i]>a[j])
temp[k++] = a[j++],ans+=m-i+1;
else
temp[k++] = a[i++];
while (i <= m) temp[k++] = a[i++];
while (j <= r) temp[k++] = a[j++];
for (int i = l;i<= r;i++)
a[i] = temp[i];
}
int main()
{
// freopen("F:\\rush.txt","r",stdin);
rei(n);
rep1(i,1,n)
rel(a[i]);
mergesort(1,n);
cout << ans << endl;
return 0;
}
【t099】最接近神的人的更多相关文章
- 洛谷P1774 最接近神的人_NOI导刊2010提高(02)(求逆序对)
To 洛谷.1774 最接近神的人 题目描述 破解了符文之语,小FF开启了通往地下的道路.当他走到最底层时,发现正前方有一扇巨石门,门上雕刻着一幅古代人进行某种活动的图案.而石门上方用古代文写着“神的 ...
- [NOI导刊2010提高&洛谷P1774]最接近神的人 题解(树状数组求逆序对)
[NOI导刊2010提高&洛谷P1774]最接近神的人 Description 破解了符文之语,小FF开启了通往地下的道路.当他走到最底层时,发现正前方有一扇巨石门,门上雕刻着一幅古代人进行某 ...
- 【洛谷P1774】最接近神的人
最接近神的人_NOI导刊2010提高(02) 用类似于桶的方法,树状数组记录原序列的某位置之前已经插入了多少个数, 插入时树状数组单点加1即可 先排一遍序,从大到小插入所有数在原序列的位置, 统计每次 ...
- P1774 最接近神的人_NOI导刊2010提高(02)
P1774 最接近神的人_NOI导刊2010提高(02) 关于此题为什么可以使用求逆序对的方法来做 假设一个数\(a_i\),且前\(i-1\)个数已经成为单调增的数列. 我们要从前\(a_1\)至\ ...
- 洛谷——P1966 火柴排队&&P1774 最接近神的人_NOI导刊2010提高(02)
P1966 火柴排队 这题贪心显然,即将两序列中第k大的数的位置保持一致,证明略: 树状数组求逆序对啦 浅谈树状数组求逆序对及离散化的几种方式及应用 方法:从前向后每次将数插入到bit(树状数组)中, ...
- luoguP1774 最接近神的人_NOI导刊2010提高(02)x
P1774 最接近神的人_NOI导刊2010提高(02) 题目描述 破解了符文之语,小FF开启了通往地下的道路.当他走到最底层时,发现正前方有一扇巨石门,门上雕刻着一幅古代人进行某种活动的图案.而石门 ...
- 洛谷P1774 最接近神的人_NOI导刊2010提高(02) [2017年6月计划 线段树03]
P1774 最接近神的人_NOI导刊2010提高(02) 题目描述 破解了符文之语,小FF开启了通往地下的道路.当他走到最底层时,发现正前方有一扇巨石门,门上雕刻着一幅古代人进行某种活动的图案.而石门 ...
- P1774 最接近神的人_NOI导刊2010[树状数组 逆序对 离散化]
题目描述 破解了符文之语,小FF开启了通往地下的道路.当他走到最底层时,发现正前方有一扇巨石门,门上雕刻着一幅古代人进行某种活动的图案.而石门上方用古代文写着“神的殿堂”.小FF猜想里面应该就有王室的 ...
- 洛谷P1774 最接近神的人
题目描述 破解了符文之语,小FF开启了通往地下的道路.当他走到最底层时,发现正前方有一扇巨石门,门上雕刻着一幅古代人进行某种活动的图案.而石门上方用古代文写着“神的殿堂”.小FF猜想里面应该就有王室的 ...
随机推荐
- errpt命令
errpt –a 详细信息 errpt -a –s [TIMESTAMP] errpt –aj [IDENTIFIER] errclear 清除(后面接参数) errpt -aj BFE4C025 ...
- ssm 框架学习-1
理论理解 +项目阅读 SpringSpring就像是整个项目中装配bean的大工厂,在配置文件中可以指定使用特定的参数去调用实体类的构造方法来实例化对象.Spring的核心思想是IoC(控制反转),即 ...
- Springboot2.0访问Redis集群
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作高性能的key-value数据库.缓存和消息中间件,掌握它是程序员的必备技能,下面是一个springboot访问redis的 ...
- VS:"64位调试操作花费的时间比预期要长"的一解决途径
解决的方法之中的一个: 在命令提示符那里打入例如以下命令: netsh winsock reset catalog netsh int ip reset reset.log hit 重新启动电脑后,就 ...
- 1.22 Python基础知识 - 正则表达式
Python正则表达式 正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配. Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式. re ...
- C# 截取中英文混合字符串分行显示宽度相同
/// <summary> /// 截取方法名显示宽度 /// </summary> /// <param name=" ...
- go reflect 调用方法
package main import ( "fmt" "reflect" ) type A struct { } func (A) Test() { fmt. ...
- JS前端监控机制的建立
JS前端监控机制: 1.采用try...catch...,和window.onerror的形式. 2.最终形成错误日志文件,并发送邮件和短信的形式进行报警. 3.如果是跨域请求,在script标签上要 ...
- 支付宝支付Java后台总结
这个支付的流程是前端H5(APP等)需要支付时调用后台的接口拿到我们加密的签名去调起支付宝的支付界面(支付宝APP)进行支付操作,并且前端在支付成功后,支付宝后台会回调一个我们在签名时写入的一个接口地 ...
- 计科1111-1114班第一次实验作业(NPC问题——回溯算法、聚类分析)
实验课安排 地点: 科技楼423 时间: 计科3-4班---15周周一上午.周二下午 计科1-2班---15周周一下午.周二晚上(晚上时间从18:30-21:10) 请各班学委在实验课前飞信通知大家 ...