點此看題面
大致題意:有\(a\)和\(b\)兩個陣列,問你要將\(b\)進行多少次相鄰兩數交換操作,才能使得\(\sum_^n(a_i-b_i)^2\)最小。
不難猜到,當\(a\)中第\(i\)小的數與\(b\)中第\(i\)小的數配對時,值最小。
證明以\(n=2\)為例(\(n>2\)同理),設\(a_1,此時只有兩種匹配方式:
\(s_1=(a_1-b_1)^2+(a_2-b_2)^2=a_1^2+a_2^2+b_1^2+b_2^2-2a_1b_1-2a_2b_2\)
\(s_2=(a_1-b_2)^2+(a_2-b_1)^2=a_1^2+a_2^2+b_1^2+b_2^2-2a_1b_2-2a_2b_1\)
則用\(s_1\)減\(s_2\)得:
\[s_1-s_2=-2(a_1b_1+a_2b_2-a_1b_2-a_2b_1)=-2(a_2-a_1)(b_2-b_1)
\]\[\because a_1
原命題得證。
設\(rb_i\)為\(b_i\)是\(b\)序列中第幾小的數,則我們可以得出乙個序列\(s\),其中\(s_i\)表示\(a\)序列中第\(rb_i\)小的數的位置。
那麼題意就變成了求要對\(s\)序列進行多少次氣泡排序操作,才可以使\(s\)有序。
根據乙個著名定理,氣泡排序操作次數即為逆序對個數。
因此我們直接逆序對做即可。
我採用的是歸併排序,具體實現見**。
#include#define tp template#define ts template#define reg register
#define ri reg int
#define con const
#define ci con int&
#define i inline
#define w while
#define n 100000
#define x 99999997
#define inc(x,y) ((x+=(y))>=x&&(x-=x))
using namespace std;
int n,s[n+5];
struct data
i bool operator < (con data& o) con
public:
i void solve()
}m;int main()
洛谷P1966 火柴排隊 逆序對
題目鏈結 不算很難的一道題 首先要保證權值最小,不難想到一種貪心策略,即把兩個序列中rank相同的數放到同乙個位置 證明也比較trivial。假設 a 中有兩個元素 a,b b 中有兩個元素 c,d 然後分別討論一下當 a b 時 c 與 a 對應優還是與 b 對應優。化簡的時候直接對兩個式子做差。...
洛谷 1966 火柴排隊
題目描述 涵涵有兩盒火柴,每盒裝有 n 根火柴,每根火柴都有乙個高度。現在將每盒中的火柴各自排成一列,同一列火柴的高度互不相同,兩列火柴之間的距離定義為 a i bi 2 ai bi 2 ai b i 2其中ai 表示第一列火柴中第i個火柴的高度,bi 表示第二列火柴中第 iii 個火柴的高度。每列...
求逆序對 思維 火柴排隊(洛谷 P1966)
題目描述 涵涵有兩盒火柴,每盒裝有 n 根火柴,每根火柴都有乙個高度。現在將每盒中的火柴各自排成一列,同一列火柴的高度互不相同,兩列火柴之間的距離定義為 ai bi 2 其中 ai 表示第一列火柴中第 i 個火柴的高度,bi 表示第二列火柴中第 i 個火柴的高度。每列火柴中相鄰兩根火柴的位置都可以交...