【归并排序】奶牛的图片(jzoj 1812)
生活随笔
收集整理的這篇文章主要介紹了
【归并排序】奶牛的图片(jzoj 1812)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
奶牛的圖片
jzoj 1812
題目大意
給你一個序列,你可以交換相鄰的兩個數
讓你用最少的交換次數來使得這個序列變成形如a+1,a+2...n,1,2...a?1,aa+1,a+2...n,1,2...a-1,aa+1,a+2...n,1,2...a?1,a的序列
問你最少的交換次數是多少次
輸入樣例
5 3 5 4 2 1輸出樣例
2解題思路
如果我們變成1,2...n1,2...n1,2...n所需次數就是他的逆序對(證明上網找)
如果我們把1放到n后面,那逆序對就要減去1原來的貢獻再加上1現在的貢獻
就是?(si?1)+(n?si)-(s_i - 1)+(n-s_i)?(si??1)+(n?si?),然后枚舉每一種情況,求最小解
注:sis_isi?是指iii的初始位置
代碼
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long using namespace std; ll n, g, ans, a[100010], b[100010], s[100010]; void work(ll l, ll r)//歸并排序求逆序對 {if (l >= r) return;ll mid = (l + r) / 2;ll L = l, R = mid + 1;work(l, mid);work(mid + 1, r);for (ll i = l; i <= r; ++i){if ((a[L] < a[R] || R > r) && L <= mid) b[i] = a[L++];else {b[i] = a[R++];g += mid - L + 1;}}for (ll i = l; i <= r; ++i)a[i] = b[i];return; } int main() {scanf("%lld", &n);for (ll i = 1; i <= n; ++i){scanf("%lld", &a[i]); s[a[i]] = i;}work(1, n);ans = g;for (ll i = 1; i < n; ++i){g = g - (s[i] - 1) + (n - s[i]);//把當前的第一個數放到最后ans = min(ans, g); }printf("%lld", ans);return 0; }總結
以上是生活随笔為你收集整理的【归并排序】奶牛的图片(jzoj 1812)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【数学】奶牛编号(jzoj 2932)
- 下一篇: 【斜率优化】玩具装箱(luogu 319