小朋友排队
来源:互联网 发布:dvd电子相册制作软件 编辑:程序博客网 时间:2024/04/28 10:09
问题描述
n 个小朋友站成一排。现在要把他们按身高从低到高的顺序排列,但是每次只能交换位置相邻的两个小朋友。
每个小朋友都有一个不高兴的程度。开始的时候,所有小朋友的不高兴程度都是0。
如果某个小朋友第一次被要求交换,则他的不高兴程度增加1,如果第二次要求他交换,则他的不高兴程度增加2(即不高兴程度为3),依次类推。当要求某个小朋友第k次交换时,他的不高兴程度增加k。
请问,要让所有小朋友按从低到高排队,他们的不高兴程度之和最小是多少。
如果有两个小朋友身高一样,则他们谁站在谁前面是没有关系的。
每个小朋友都有一个不高兴的程度。开始的时候,所有小朋友的不高兴程度都是0。
如果某个小朋友第一次被要求交换,则他的不高兴程度增加1,如果第二次要求他交换,则他的不高兴程度增加2(即不高兴程度为3),依次类推。当要求某个小朋友第k次交换时,他的不高兴程度增加k。
请问,要让所有小朋友按从低到高排队,他们的不高兴程度之和最小是多少。
如果有两个小朋友身高一样,则他们谁站在谁前面是没有关系的。
输入格式
输入的第一行包含一个整数n,表示小朋友的个数。
第二行包含 n 个整数 H1 H2 … Hn,分别表示每个小朋友的身高。
第二行包含 n 个整数 H1 H2 … Hn,分别表示每个小朋友的身高。
输出格式
输出一行,包含一个整数,表示小朋友的不高兴程度和的最小值。
样例输入
3
3 2 1
3 2 1
样例输出
9
样例说明
首先交换身高为3和2的小朋友,再交换身高为3和1的小朋友,再交换身高为2和1的小朋友,每个小朋友的不高兴程度都是3,总和为9。
数据规模和约定
对于10%的数据, 1<=n<=10;
对于30%的数据, 1<=n<=1000;
对于50%的数据, 1<=n<=10000;
对于100%的数据,1<=n<=100000,0<=Hi<=1000000。
对于30%的数据, 1<=n<=1000;
对于50%的数据, 1<=n<=10000;
对于100%的数据,1<=n<=100000,0<=Hi<=1000000。
归并排序。在合并的时候处理不高兴程度。
刚开始求累加居然用了二重循环,,,excuse me?! 后来发现,直接递推就好了- - 时间这个问题就解决了。
然后开始忘记了用longlong,毕竟10000的累加并不是个小数目,而且要把n个累加都加在一起,很大可能就越界了。
#include <stdio.h>#include <math.h>int n, unhappy[100005];long long sum[100005], s[100005], ans;//之前一直挂在这个长整型!!! typedef struct{int h, no;}aa;aa a[100005], b[100005];void leijia(){int i;sum[1] = 1;for(i = 2 ; i <= n ; i++)sum[i] += (sum[i-1] + i);}void mergearray(int l, int mid, int r){int i = l, ii = mid, j = mid+1, jj = r, k = 0, t;while(i <= ii && j <= jj){if(a[i].h <= a[j].h){t = k + l - i;//前半部分的数落到下边的数组,序号肯定是小于下边数组的序号 unhappy[a[i].no] += t;s[a[i].no] = sum[unhappy[a[i].no]];b[k].h = a[i].h;b[k].no = a[i].no;k++;i++;}else {t = j - k - l;//后半部分的数落到下边的数组,序号肯定是大于下边数组的序号 unhappy[a[j].no] += t;s[a[j].no] = sum[unhappy[a[j].no]]; b[k].h = a[j].h; b[k].no = a[j].no; k++; j++;}}while(i <= ii){t = k + l - i;//前半部分的数落到下边的数组,序号肯定会小 unhappy[a[i].no] += t;s[a[i].no] = sum[unhappy[a[i].no]];b[k].h = a[i].h;b[k].no = a[i].no;k++;i++;}while(j <= jj)//后半部分直接落下来 ,不会变动位置 {b[k].h = a[j].h;b[k].no = a[j].no;k++;j++;}for(i = 0 ; i < k ; i++){a[i + l].h = b[i].h;a[i + l].no = b[i].no;}}void mergesort(int l, int r){if(l < r){int mid = (l + r) / 2;mergesort(l, mid);mergesort(mid+1, r);mergearray(l, mid, r);}}int main(){int i;scanf("%d", &n);leijia();for(i = 0 ; i < n ; i++){ scanf("%d", &a[i].h); a[i].no = i;}mergesort(0, n-1);for(i = 0 ; i < n ; i++)ans += s[i];printf("%I64d\n", ans);return 0;}
0 0
- 小朋友排队
- 小朋友排队
- 小朋友排队
- 小朋友排队
- 小朋友排队
- 小朋友排队
- 小朋友排队
- 小朋友排队
- 小朋友排队
- 小朋友排队
- 小朋友排队
- 小朋友排队
- 小朋友排队--第五届蓝桥杯
- 蓝桥杯 小朋友排队
- 小朋友排队 蓝桥杯
- 历届试题 小朋友排队
- 蓝桥杯 小朋友排队
- 1010-小朋友排队
- HDU 1010 深度搜索问题
- HDOJ-2032
- 注册新用户(perl)
- nyoj477 A+B=C
- MySQL知识(二)——数据表的基本操作
- 小朋友排队
- HSRP
- C语言const的用法
- CSS实现响应式正方形
- PHP web 安全
- Spark分布式计算执行模型
- 类实例定义
- 如何在Android studio上使用Github(图文详尽版---附一些常用错误)
- JBOSS的下载安装、环境变量配置以及部署