小朋友排队


标题:小朋友排队

    n 个小朋友站成一排。现在要把他们按身高从低到高的顺序排列,但是每次只能交换位置相邻的两个小朋友。

    每个小朋友都有一个不高兴的程度。开始的时候,所有小朋友的不高兴程度都是0。

    如果某个小朋友第一次被要求交换,则他的不高兴程度增加1,如果第二次要求他交换,则他的不高兴程度增加2(即不高兴程度为3),依次类推。当要求某个小朋友第k次交换时,他的不高兴程度增加k。

    请问,要让所有小朋友按从低到高排队,他们的不高兴程度之和最小是多少。

    如果有两个小朋友身高一样,则他们谁站在谁前面是没有关系的。

【数据格式】

    输入的第一行包含一个整数n,表示小朋友的个数。
    第二行包含 n 个整数 H1 H2 … Hn,分别表示每个小朋友的身高。
    输出一行,包含一个整数,表示小朋友的不高兴程度和的最小值。

例如,输入:
3
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。

当n接近1e5的时候,我犯了溢出错误。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 const int MS=100005;
 7 typedef long long LL;
 8 
 9 struct node
10 {
11     int h;
12     int time;
13 }nodes[MS];
14 
15 void merge(node *a,int low,int high)    
16 {
17     int b1=low;
18     int mid=(low+high)/2;
19     int b2=mid+1;
20     node *b=(node *)malloc((high-low+1)*sizeof(node));
21     int k=0;
22     while(b1<=mid&&b2<=high)
23     {
24         if(a[b1].h<=a[b2].h)
25         {
26             a[b1].time+=b2-mid-1;  //在a[b1]的右边,a[b2]的左边有b2-mid-1个数比a[b1]小     
27             b[k++]=a[b1++];            // 如果不是的话,那么a[b1]早就加入了   这里不会出现a[b2]的前面有与a[b2]相等的数 
28         }                            //如果mid的右边有连续相同的数,那么a[b2]一定是第一个 
29         else
30         {
31             a[b2].time+=mid-b1+1;   //如果是求逆序对的话,只要插入这一句就可以了 
32             b[k++]=a[b2++];
33         }
34     }
35     while(b1<=mid)
36     {
37         a[b1].time+=high-mid;  //这里也要加
38         b[k++]=a[b1++];
39     }
40     while(b2<=high)
41         b[k++]=a[b2++];
42     for(int i=0;i<k;i++)
43     {
44         a[low++]=b[i];
45     }
46     free(b);
47     return ; 
48 } 
49 
50 void merge_sort(node *a,int low,int high)
51 {
52     if(low<high)
53     {
54         int mid=(low+high)/2;
55         merge_sort(a,low,mid);
56         merge_sort(a,mid+1,high);
57         merge(a,low,high);
58     }
59 }
60  
61 int main()
62 {
63     int n;
64     scanf("%d",&n);
65     for(int i=0;i<n;i++)
66     {
67         scanf("%d",&nodes[i].h);
68         nodes[i].time=0;
69     }
70     merge_sort(nodes,0,n-1);
71     LL ans=0;
72     
73     for(int i=0;i<n;i++)
74     {
75         LL t=nodes[i].time;
76         ans+=(t+1)*t/2;   //注意  (t+1)*t溢出 
77     }
78     printf("%I64d\n",ans);
79     return 0;
80 }
81  

 

posted @ 2015-02-20 09:45  daydaycode  阅读(212)  评论(0编辑  收藏  举报