博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
hdu 6318 Swaps and Inversions(归并排序)
阅读量:4450 次
发布时间:2019-06-07

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

Swaps and Inversions

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 1212    Accepted Submission(s): 448

Problem Description

Long long ago, there was an integer sequence a.

Tonyfang think this sequence is messy, so he will count the number of inversions in this sequence. Because he is angry, you will have to pay x yuan for every inversion in the sequence.
You don't want to pay too much, so you can try to play some tricks before he sees this sequence. You can pay y yuan to swap any two adjacent elements.
What is the minimum amount of money you need to spend?
The definition of inversion in this problem is pair (i,j) which 1≤i<j≤n and ai>aj.

Input

There are multiple test cases, please read till the end of input file.

For each test, in the first line, three integers, n,x,y, n represents the length of the sequence.
In the second line, n integers separated by spaces, representing the orginal sequence a.
1≤n,x,y≤100000, numbers in the sequence are in [−109,109]. There're 10 test cases.

Output

For every test case, a single integer representing minimum money to pay.

Sample Input

3 233 666 1 2 3 3 1 666 3 2 1

Sample Output

0 3

题目链接:

题意:这道题的意思是说给你一个数组,你可以花x元或者y元去交换这个数组中相邻的两个数,问变为升序的时候最少花费多少元。

当时听(队友讲的)这个题的时候,脑子里第一反应是冒泡(没用过归并),肯定超时。最后我们也没有解决这个题。

作为菜鸟(手动笑哭)我还是先说一下归并排序吧!

把一个数组分成两半,先把前一半排序,再把后一半排序,把两半归并到一个新的数组中,然后在拷贝回原来的数组中。

归并排序测试:

AC代码:

#include 
#include
#include
#include
#include
#include
#include
using namespace std;int a[100001],b[100001];void Merge(int s,int m,int e){ int p=0; int p1=s,p2=m+1;//一个指向第一个数组中的第一个数,一个指向第二个数组中的第一个数 while(p1<=m&&p2<=e) { if(a[p1]
(n-1)排序 for(int i=0;i

下面就来看这道题:会了归并排序以后这道题就简单很多了。下面就说怎么计算交换的次数。

s<=p1<=m,m+1<=p2<=e;

可以看图,在归并时,当a[p2]需要添加在数组中的时候,它必须要和1后面所有的数字交换,次数是:m-s+1;

下面看AC代码:

#include 
#include
#include
#include
#include
#include
#include
using namespace std;int a[100001],b[100001];long long times;void Merge(int s,int m,int e){ int p=0; int p1=s,p2=m+1; while(p1<=m&&p2<=e) { if(a[p1]<=a[p2])//因为需要最小次数,所以这里是<= b[p++]=a[p1++]; else { b[p++]=a[p2++]; times+=m-p1+1; } } while(p1<=m) b[p++]=a[p1++]; while(p2<=e) b[p++]=a[p2++]; for(int i=0;i

刚开始因为while(~scanf("%d%d%d",&n,&x,&y))没有以EOF结束,T了n遍,后来不知道怎么就看出来了,然后就是<=那个地方和数据范围那里。一下午就做了两个题,一个是第一场贪心那个题,WA了n次,决定学了数据结构之后再去做,另外一个就是这个,在超时,超内存n次之后终于AC了。还是做得题太少了,就算当时会了归并,我觉得我有可能还是做不出来。找不到题的坑点(流泪)。

转载于:https://www.cnblogs.com/zut-syp/p/10543740.html

你可能感兴趣的文章
USACO 3.1 Contact
查看>>
Office之什么是高内聚低耦合
查看>>
一些奇怪的问题求回答
查看>>
这些年踩过的坑
查看>>
iOS开发拓展篇——如何把项目托管到GitHub
查看>>
性能优化之数据库优化
查看>>
类的继承、菱形继承、派生、多态
查看>>
mysql约束
查看>>
javascript鼠标及键盘事件总结及案例
查看>>
mysql表之间的关系及级联操作
查看>>
mac 搭建virtualenv的那些坑
查看>>
多路复用IO模型
查看>>
并发、串行、并行及多道技术原理
查看>>
hashlib、pickle、hmac、logging模块使用
查看>>
javascript常用知识点总结
查看>>
2019秋招复习笔记--数据库基本操作
查看>>
2019秋招复习笔试--手写代码
查看>>
2019秋招复习笔记--智力题
查看>>
MySQL学习笔记
查看>>
2019秋招面试复习 项目重点提问
查看>>