洛谷 P1966 火柴排隊

2022-05-21 20:06:34 字數 2676 閱讀 6302

題面

先研究第乙個問題:如何使得"距離"最小。

可以發現題意就是要求一種合適的兩組數間的配對方式,使得∑(ai-bi)^2最小。

我口胡了乙個結論...就是最好的配對方式,就是兩組數分別排好序後,將位置相同的兩個元素配對。

當然,可以發現這個結論是對的:

(以下內容僅為記錄)

題目的意思:min

展開:min=min

仔細觀察,可以發現∑ai^2和∑bi^2的值是不會變的,所以只能在∑2*ai*bi上做文章。

為使得和最小,那麼∑2*ai*bi要最大,本題的模型就轉變為max。(2為常數,可省略)

對兩個陣列分別進行排序後,現有第乙個陣列中兩個數a和b,第二個陣列中兩個數c和d

a<=b c<=d

根據以上猜測,則ac+bd一定是最大的。利用反證法。

若ac+bd不是最大的,那麼一定有比它更大的,只有ad+bc

如果c=d,那麼顯然ac+bd=ad+bc,不會更大

如果cb,與a<=b矛盾

首先讀入兩個陣列a1,b。將a1放入乙個結構體陣列a,結構體有成員a,b,num,a表示a1陣列中對應位置的值,num表示最初的位置,b空著。

此時得到x1:就是開始時的b陣列。

然後將a以結構體的成員a為關鍵字排序,將b排序(都是從小到大)。再將b中元素按此時的順序賦給a的成員(意會一下)。這樣就能得到最好的配對方式(兩組數分別排好序後,將位置相同的兩個元素配對)。

再將a以結構體成員num為關鍵字排序。此時得到x2:就是將a中結構體成員b按順序抽出組成的新陣列。

那麼,問題就轉化為在只能進行交換相鄰兩數的操作時,將x1用最少步數變成x2。

這裡的方法是:將x1中每個數字變為其在x2中最後一次出現的位置。問題就變成將新的x1變成從小到大的最少步數。

這個問題的答案,其實就是新的x1的逆序對個數。因為:每一次交換相鄰兩數,不會改變其他數和這兩個數的相對位置,因此只會導致逆序對個數加1、減1或不變。那麼,可以設法使得每一次交換都恰好交換逆序的兩數(很顯然是可以做到的)。這兒有個解釋:

1 #include2 #include3 #include4

#define md 99999997

5using

namespace

std;

6 typedef long

long

ll;7

structx8

14 }a[100100

];15 mapma;

16ll now,n;

17 ll x1[100100],ans,t1[100100

];18

bool cmp(const x& a,const x&b)

1922

void

sort2(ll l,ll r)

2335

else

36 t1[k++]=x1[i++];37}

38for(;i<=m;)

39 t1[k++]=x1[i++];

40for(;j<=r;)

41 t1[k++]=x1[j++];

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

43 x1[i]=t1[i];44}

45int

main()

4658 sort(a+1,a+n+1

);59 sort(t1+1,t1+n+1

);60

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

61 a[i].b=t1[i];

62 sort(a+1,a+n+1

,cmp);

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

64 ma[a[i].b]=++now;

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

66 x1[i]=ma[x1[i]];

67 sort2(1

,n);

68 printf("

%lld

",ans);

69return0;

70 }

錯誤**:

1 #include2 #include3 #include4

#define md 99999997

5using

namespace

std;

6 typedef long

long

ll;7

structx8

14 }a[100100

];15 ll a1[100100],t1[100100

];16

ll n,ans;

17void

sort2(ll l,ll r)

1830

else

31 t1[k++]=a1[i++];32}

33for(;i<=m;)

34 t1[k++]=a1[i++];

35for(;j<=r;)

36 t1[k++]=a1[j++];

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

38 a1[i]=t1[i];39}

40int

main()

41

還是na1ve。

洛谷 P1966 火柴排隊

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

洛谷P1966 火柴排隊

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

洛谷P1966 火柴排隊

火柴排隊 感覺比較順理成章地就能推出來?似乎是個一眼題 交換的話多半會往逆序對上面想,然後題目給那個式子就是拿來嚇人的根本沒有卵用 唯一的用處大概是告訴你考慮貪心一波,很顯然有兩個序列中每對排名對應的數放在同一位置上是最優策略這個結論 說詳細一點,假設 a 0 是 a 序列中的第 k 大,b 0 是...