最小逆序数

来源:互联网 发布:婚纱照一键修图软件 编辑:程序博客网 时间:2024/06/06 09:26

问题描述:有一个长度为 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 intstruct 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);elseprintf("0\n"); return 0;}     /*输入示例:3 12 2 13 02 2 1输出示例:12 */     


0 0