您的位置:首页 > 其它

最小逆序数

2015-12-18 15:23 344 查看
问题描述:有一个长度为 n 个正整数序列{a0,a1,…,an-1}。定义一次操作为:交换序列中任意两个相邻的元素。求不超过 k 次操作后,这个序列的最小的逆序数。

#include<stdio.h>
#include<stdlib.h>
#define minin(a,b)  a<b?a:b
#define less(a,b)	a<=b
#define item int
struct bag
{
item*a;
item*b;
bool flag;
__int64 num;
void init(int n){a=(int*)malloc((n+1)*sizeof(int)); b=(int*)malloc((n+1)*sizeof(int)); flag=0;num=0;}
void change(){item*c=a;a=b;b=c;flag=!flag;}
};
int n;
void merge(bag* test,int l,int m,int r)
{
int i=m,j=r,k=r;
item*a=test->a,*b=test->b;
while((i>=l)&&(j>m))
{
if(less(a[i],a[j]))b[k--]=a[j--];
else
{
b[k--]=a[i--];
test->num+=j-m;
}
}
if(i<l)for(i=j;i>m;i--)b[k--]=a[i];
else for(;i>=l;i--)b[k--]=a[i];
}

void mergesortBU(bag* test,int l,int r)
{
int i,m,num=0;
for(m=1;m<=r-l;m=m+m)
{
for(i=l;i<=r-m;i+=m+m)
merge(test,i,i+m-1,minin(i+m+m-1,r));
while(i<=r)
test->b[i]=test->a[i++];
test->change();
}
}

int main()
{
int k,i;
scanf("%d%d",&n,&k);
bag* test=(bag*)malloc(sizeof(bag));
test->init(n);
for(i=1;i<=n;i++)
scanf("%d",&test->a[i]);
mergesortBU(test,1,n);
if((test->num=test->num-k)>0)
printf("%I64d\n",test->num);
else
printf("0\n");
return 0;
}

/*
输入示例:
3 1
2 2 1
3 0
2 2 1

输出示例:
1
2

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: