1966 火柴排隊

2022-08-01 06:33:19 字數 2895 閱讀 6146

難度:提高+/省選-

題目型別:貪心/分治

提交次數:5

涉及知識:逆序對、離散化

涵涵有兩盒火柴,每盒裝有 n 根火柴,每根火柴都有乙個高度。 現在將每盒中的火柴各自排成一列, 同一列火柴的高度互不相同, 兩列火柴之間的距離定義為: ∑(ai-bi)^2

其中 ai 表示第一列火柴中第 i 個火柴的高度,bi 表示第二列火柴中第 i 個火柴的高度。

每列火柴中相鄰兩根火柴的位置都可以交換,請你通過交換使得兩列火柴之間的距離最小。請問得到這個最小的距離,最少需要交換多少次?如果這個數字太大,請輸出這個最小交換次數對 99,999,997 取模的結果。

輸入格式:

輸入檔案為 match.in。

共三行,第一行包含乙個整數 n,表示每盒中火柴的數目。

第二行有 n 個整數,每兩個整數之間用乙個空格隔開,表示第一列火柴的高度。

第三行有 n 個整數,每兩個整數之間用乙個空格隔開,表示第二列火柴的高度。

輸出格式:

輸出檔案為 match.out。

輸出共一行,包含乙個整數,表示最少交換次數對 99,999,997 取模的結果。

輸入樣例#1:

【輸入輸出樣例 1】

42 3 1 4

3 2 1 4

【輸入輸出樣例 2】

41 3 4 2

1 7 2 4

輸出樣例#1:

【輸入輸出樣例 1】

1【輸入輸出樣例 2】

2

【輸入輸出樣例說明1】

最小距離是 0,最少需要交換 1 次,比如:交換第 1 列的前 2 根火柴或者交換第 2 列的前 2 根火柴。

【輸入輸出樣例說明2】

最小距離是 10,最少需要交換 2 次,比如:交換第 1 列的中間 2 根火柴的位置,再交換第 2 列中後 2 根火柴的位置。

【資料範圍】

對於 10%的資料, 1 ≤ n ≤ 10;

對於 30%的資料,1 ≤ n ≤ 100;

對於 60%的資料,1 ≤ n ≤ 1,000;

對於 100%的資料,1 ≤ n ≤ 100,000,0 ≤火柴高度≤ maxlongint

**:

1 #include2 #include3

using

namespace

std;

4intn;5

6struct

nodea[100005],b[100005

];10

11bool

cmp(node n1, node n2)

1415

int f[100005

];16

int temp[100005

];17

int ans = 0;18

19void merge(int l, int m, int

r)26

else

27 temp[k++] = f[i++];28}

29while(i <=m)

30 temp[k++] = f[i++];

31while(j <=r)

32 temp[k++] = f[j++];

33for(i = l; i <= r; i++)

34 f[i] =temp[i];

35}

3637

void merge_sort(int l, int

r)4445}

46int

main()

53for(i = 1; i <= n; i++)

57 sort(a+1, a+n+1

, cmp);

58 sort(b+1, b+n+1

, cmp);

59for(i = 1; i <= n; i++)

60f[a[i].no] = b[i].no;//

構造對映

61//

我們的目的:使a中第i大的數和b中第i大的數對齊

62//

a數列中第a[i].no位置的數,應該排在b[i].no位置,所以其實際價值為b[i].no

63//

從小到大排序,求逆序對

64 merge_sort(1

, n);

65 cout66return0;

67 }

備註:

上週講的貪心專題中的一道題。首先是固定一行火柴不動,交換另一行火柴,使火柴的大小關係相對應。∑(ai-bi)^2展開之後可以發現,就是自招課上提到過的排序不等式,所以大小關係相對應時結果最小,也可以用數學歸納法證明。

接下來就轉變成了乙個找逆序對的問題。為什麼是找逆序對呢?直觀上是因為只能交換相鄰兩根火柴……老師課上好像給了證明,「假設a和b逆序且不相鄰,則存在與a相鄰逆序對"。算了我不太明白我也不想想了。

第乙個問題就是f[a[i].no] = b[i].no,我可是琢磨了一中午這個道理。先把ab都排好序,對於a中第a[i].no個數,它的目標位置在第b[i].no個,那我們就認為這個位置的數的實際價值為b[i].no,這樣對f陣列進行排序就可以讓大家各回各家(這個過程中找逆序對)。。實際上就是乙個離散化的過程。我可能理解的還不是很深刻。

我媽來接我了我要回家了。

另外乙個問題就是取模錯了。導致一直80分……

luogu1966 火柴排隊

題目描述 涵涵有兩盒火柴,每盒裝有 n 根火柴,每根火柴都有乙個高度。現在將每盒中的火柴各自排成一列,同一列火柴的高度互不相同,兩列火柴之間的距離定義為 ai bi 2 其中 ai 表示第一列火柴中第 i 個火柴的高度,bi 表示第二列火柴中第 i 個火柴的高度。每列火柴中相鄰兩根火柴的位置都可以交...

P1966 火柴排隊

題意 求兩個為n的序列貢獻值最小需要怎麼移動才能達到,移動 交換相鄰元素,貢獻值 ai bi 2。顯然可以猜出來,排序過後對應的最小。事實上也可以用反證法證明aac bd最小 我們令上面的序列不動,只動下面的序列,首先得到下面序列應該是怎麼樣的。用標號來標誌原來位置,排序過後,把對應位置賦值到陣列上...

洛谷 1966 火柴排隊

題目描述 涵涵有兩盒火柴,每盒裝有 n 根火柴,每根火柴都有乙個高度。現在將每盒中的火柴各自排成一列,同一列火柴的高度互不相同,兩列火柴之間的距離定義為 a i bi 2 ai bi 2 ai b i 2其中ai 表示第一列火柴中第i個火柴的高度,bi 表示第二列火柴中第 iii 個火柴的高度。每列...