日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【归并排序】奶牛的图片(jzoj 1812)

發布時間:2023/12/3 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【归并排序】奶牛的图片(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)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。