http://acm.hdu.edu.cn/showproblem.php?pid=1394
题意:给定无序的n个数 0~n-1,可以这样变幻得到n的不同的序列:每次将序列中第一个数放到最后一个。
问在这n个序列中逆序对数最少是多少?
思路:
已知逆序对数的定义后,可以直接暴力求原序列的逆序对数,设为sum;可以发现以后n-1个的序列的逆序对数就知道了,不难证明,两个相邻序列的逆序对数差值为 n-1-2*x。
这个题可以直接暴力过,也可以线段树过。一开始是没想到怎么用线段树做。看了题解才明白。
首先建树,节点中有一个num域,如果某个数在该区间中,那么该区间的num值加1。相当于数x在线段树中走一遍,用num来记录它的足迹(个人理解)。每输入一个数x就查询在区间[x+1,n-1]中的num值,也就是在输入x之前比x大的数的个数,正好对应逆序对数的定义。然后再把x插入线段树中。这样就把原序列的逆序对数求出来了。
#include <stdio.h>
#include <string.h>
const int maxn = 5005;
struct line
{
int l;
int r;
int num;
}tree[maxn<<2];
void build(int v, int l, int r)
{
tree[v].l = l;
tree[v].r = r;
tree[v].num = 0;
if(l == r)
return;
int mid = (l+r)>>1;
build(v*2,l,mid);
build(v*2+1,mid+1,r);
}
//区间求和
int query(int v, int l, int r)
{
if(tree[v].l == l && tree[v].r == r)
return tree[v].num;
int mid = (tree[v].l + tree[v].r)>>1;
if(r <= mid)
return query(v*2,l,r);
else if(l > mid)
return query(v*2+1,l,r);
else return query(v*2,l,mid) + query(v*2+1,mid+1,r);
}
void update(int v, int x)
{
if(tree[v].l <= x && tree[v].r >= x)
tree[v].num++; //记录x的踪迹
if(tree[v].l == tree[v].r)
return;
int mid = (tree[v].l+tree[v].r)>>1;
if(x <= mid)
update(v*2,x);
else update(v*2+1,x);
}
int main()
{
int n;
int a[maxn];
while(~scanf("%d",&n))
{
build(1,0,n);
int sum = 0,ans;
//求原序列的逆序对数
for(int i = 0; i < n; i++)
{
scanf("%d",&a[i]);
if(i != 0)
sum += query(1,a[i]+1,n);//每输入一个数a[i],就计算[a[i]+1,n-1]区间中已存在的数的个数
update(1,a[i]); //再把a[i]插入线段树中
}
//求其余n-1个序列的逆序对数,并求出最小值
ans = sum;
for(int i = 0; i < n; i++)
{
sum += n-1-2*a[i];
if(ans > sum)
ans = sum;
}
printf("%d\n",ans);
}
return 0;
}
暴力解法:
#include <stdio.h>
#include <string.h>
int main()
{
int n;
int a[5005];
while(~scanf("%d",&n))
{
long long num = 0;
for(int i = 0; i < n; i++)
{
scanf("%d",&a[i]);
if(i != 0)
{
for(int j = i-1; j >= 0; j--)
{
if(a[j] > a[i])
num++;
}
}
}
//printf("%d\n",num);
long long ans = num;
for(int i = 0; i < n; i++)
{
num = num + n-1-2*a[i];
if(ans > num)
ans = num;
}
printf("%lld\n",ans);
}
return 0;
}
hdu 1394 Minimum Inversion Number(逆序对数+线段树)
原文:http://blog.csdn.net/u013081425/article/details/19083607