程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 歷屆試題 小朋友排隊(樹狀數組求逆序對)

歷屆試題 小朋友排隊(樹狀數組求逆序對)

編輯:關於C語言

歷屆試題 小朋友排隊(樹狀數組求逆序對)


歷屆試題 小朋友排隊 時間限制:1.0s 內存限制:256.0MB 問題描述   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。

解題思路:采用樹狀數組的方法求解逆序對。

每個小盆友交換的次數,就是每個數左邊更大右邊更小的數的個數。 ans = 左邊與其形成的逆序對數 + 右邊與其形成的逆序對數 詳見代碼。
#include 
#include 
#include 

using namespace std;

int c[1000010],a[1000010];
__int64 sg[100010],q[100010];
int n;

int lowbit(int k)
{
	return k&(-k);
}

void add(int num,int k)
{
	while (k<1000010)
	{
		c[k]+=num;
		k+=lowbit(k);
	}
}

int sum(int k)
{
	int s=0;
	while (k)
	{
		s+=c[k];
		k-=lowbit(k);
	}
	return s;
}

int main()
{
	int i;
	q[1]=1;
	for (i=2;i<100010;i++)
	{
		q[i]=q[i-1]+i;
	}
	while (~scanf("%d",&n))
	{
		memset(c,0,sizeof(c));
		memset(sg,0,sizeof(sg));
		for (i=0;i=0;i--)
		{
			add(1,a[i]+1);
			sg[i]+=sum(a[i]);//右邊比他小的,目的是左邊比他大的加上右邊比他小的得出的是他交換的次數
		}
		//int s=Min+Max;
		__int64 ans=0;
		for (i=0;i
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved