题目:http://acm.hdu.edu.cn/showproblem.php?pid=1394
题意:给定一个长度为n的数组,每次可以把当前第一个元素放到最后面,直到数组循环一遍,问这个过程中最少的逆序对数
思路:首先求出原本数组的逆序对数,然后每次把第一个元素放到最后时,可以看出,逆序对增加了n - a[i]个,减少了a[i] - 1个,取这个过程中最小值即可
#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <cmath>
using namespace std;
typedef long long ll;
const int N = 5010;
int bit[N], level[N], n;
void add(int i, int x)
{
while(i <= n)
bit[i] += x, i += i & -i;
}
int sum(int i)
{
int s = 0;
while(i > 0)
s += bit[i], i -= i & -i;
return s;
}
int main()
{
while(~ scanf("%d", &n))
{
int a[N];
ll tmp = 0;
memset(bit, 0, sizeof bit);
for(int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
a[i]++;
add(a[i], 1);
tmp += i - sum(a[i]);
}
ll ans = tmp;
for(int i = 1; i <= n; i++)
{
tmp = tmp + (n - a[i]) - (a[i] - 1);
ans = min(ans, tmp);
}
printf("%lld\n", ans);
}
return 0;
}