Minimum Inversion Number

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 9163    Accepted Submission(s): 5642

Problem Description
The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that satisfy i < j and ai > aj.

For a given sequence of numbers a1, a2, ..., an, if we move the first m >= 0 numbers to the end of the seqence, we will obtain another sequence. There are totally n such sequences as the following:

a1, a2, ..., an-1, an (where m = 0 - the initial seqence)
a2, a3, ..., an, a1 (where m = 1)
a3, a4, ..., an, a1, a2 (where m = 2)
...
an, a1, a2, ..., an-1 (where m = n-1)

You are asked to write a program to find the minimum inversion number out of the above sequences.

 
Input
The input consists of a number of test cases. Each case consists of two lines: the first line contains a positive integer n (n <= 5000); the next line contains a permutation of the n integers from 0 to n-1.
 
Output
For each case, output the minimum inversion number on a single line.
 
Sample Input
10 1 3 6 9 0 8 5 7 4 2
 
Sample Output
16
 
Author
CHEN, Gaoli
 
Source
 
       求逆序数,这道题花了我一下午的时间去看线代,不过还好总算做出了....切克闹,切脑壳...
下 面来详细讲讲过程吧...
        首先,我求出了 Simple output 给出的 序列的 逆序数为22 这是没有错的,但是输出却为16,当时我这个小脑袋呀,真是....泪崩了呀!. 
 然后我就在这里纠结呀...哎,由于英语不是很好,居然没有读懂这句话的意思.....这是啥情况 ,妈蛋呀!
     out of the above sequences.  ------>从上面的式子中找出最小的逆序数...
     明白了这句话,下面就好办了..
    最后就是一点要说的是... 对于逆序数,如果存在左右顶端对调,并且这个序列是连续的..
是可以总结出规律的,,
看代码就知道了。。
                             time   300+ms....   c++ 
 #include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define maxn 5000
int a[maxn+];
int bb[maxn+]; //存储单个元素的逆序数
int main()
{
int n,i,j,tol;
while(scanf("%d",&n)!=EOF)
{
memset(bb,,sizeof(bb));
for(i=;i<n;i++)
{
scanf("%d",a+i);
for(j=i-;j>=;j--)
{
if(a[i]>a[j]&&bb[j]==) break;
if(a[i]<a[j])bb[i]++;
}
}
tol=;
for(i=;i<n;i++) //求出逆序数
tol+=bb[i];
int res=tol;
for(i=;i<n;i++)
{
tol+=n-*a[i]- ;
if(res>tol)
res=tol;
}
printf("%d\n",res);
} return ;
}

运用递归调用版的归并排序

比如 5 4 3 2 1 《5 ,4》,《3 ,2》  --》+ 2

 4 5 2 3 1
4 5 2 3  ---》 2 +2=4;
2 3 4 5 1 --》 4
10
运用这个原理便可以得到结果,代码如下:
 #include<string.h>
#include<stdlib.h>
#include<stdio.h>
#define maxn 5000
int aa[maxn+];
int bb[maxn+];
int nn,tol=;
void mergec(int low ,int mid ,int hight )
{
int i,j,k;
int *cc = (int *)malloc(sizeof(int)*(hight-low+));
i=low;
j=mid;
k=;
while( i<mid&&j<hight )
{
if(aa[i]>aa[j])
{
cc[k++]=aa[j++];
tol+=mid-i;
}
else
cc[k++]=aa[i++];
}
for( ; i<mid ;i++)
cc[k++]=aa[i];
for( ; j<hight ; j++)
cc[k++]=aa[j];
k=;
for(i=low;i<hight;i++)
aa[i]=cc[k++];
free( cc );
}
/*用递归求解归并排序无法求逆序数*/
void merge_sort(int st,int en)
{
int mid;
if(st+<en)
{
mid=st+(en-st)/;
merge_sort(st,mid);
merge_sort(mid,en);
mergec(st,mid,en);
}
}
int main()
{
int i,res;
// freopen("test.in","r",stdin);
while(scanf("%d",&nn)!=EOF)
{
tol=;
for(i=;i<nn;i++){
scanf("%d",aa+i);
bb[i]=aa[i];
}
merge_sort(,nn);
res=tol;
//printf("tol=%d\n",res);
for(i=;i<nn-;i++)
{
tol+=nn-*bb[i]-;
if(res>tol) res=tol;
}
printf("%d\n",res);
}
return ;
}

接下来是非递归调用....版的归并排序

 #include<string.h>
#include<stdlib.h>
#include<stdio.h>
#define maxn 5000
int aa[maxn+];
int bb[maxn+];
int nn,tol=;
void mergec(int low ,int mid ,int hight )
{
int i,j,k;
int *cc = (int *)malloc(sizeof(int)*(hight-low+));
i=low;
j=mid;
k=;
while( i<mid&&j<hight )
{
if(aa[i]>aa[j])
{
cc[k++]=aa[j++];
tol+=mid-i;
}
else
cc[k++]=aa[i++];
}
for( ; i<mid ;i++)
cc[k++]=aa[i];
for( ; j<hight ; j++)
cc[k++]=aa[j];
k=;
for(i=low;i<hight;i++)
aa[i]=cc[k++];
free( cc );
} /*----------------------华丽丽的分割线--------------------------------*/
void merge_sort( int st , int en )
{
int s,t,i;
t=;
while(t<=(en-st))
{
s=t;
t=s*; //表示两个s的长度
i=st;
while(i+t<=en){
mergec(i,i+s,i+t);
i+=t;
}
if(i+s<en)
mergec(i,i+s,en);
}
if(s<en-st)
mergec(st,st+s,en);
}
int main()
{
int i,res;
// freopen("test.in","r",stdin);
while(scanf("%d",&nn)!=EOF)
{
tol=;
for(i=;i<nn;i++){
scanf("%d",aa+i);
bb[i]=aa[i];
}
merge_sort(,nn);
res=tol;
//printf("tol=%d\n",res);
for(i=;i<nn-;i++)
{
tol+=nn-*bb[i]-;
if(res>tol) res=tol;
}
printf("%d\n",res);
}
return ;
}
 用树状数组...
代码:
 /*
用树状数组求逆序数
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define maxn 5000
int aa[maxn+];
int bb[maxn+];
int nn;
int lowbit(int k)
{
return k&(-k);
}
void ope(int x)
{
while(x<=nn)
{
aa[x]++;
x+=lowbit(x);
}
}
int sum(int x)
{
int ans=;
while(x>)
{
ans+=aa[x];
x-=lowbit(x);
}
return ans;
}
int main()
{ int i,res,ans;
//freopen("test.in","r",stdin);
while(scanf("%d",&nn)!=EOF)
{
memset(aa,,sizeof(aa));
res=;
for(i=;i<nn;i++)
{
scanf("%d",&bb[i]);
res+=sum(nn)-sum(bb[i]+);
ope(bb[i]+);
}
ans=res;
for(i=;i<nn;i++)
{
res+=nn--*bb[i];
if(ans>res)
ans=res;
}
printf("%d\n",ans);
}
return ;
}

HUDOJ-----1394Minimum Inversion Number的更多相关文章

  1. HDU 1394Minimum Inversion Number 数状数组 逆序对数量和

    Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java ...

  2. HDU 1394Minimum Inversion Number

    The inversion number of a given number sequence a1, a2, ..., an is the number of pairs (ai, aj) that ...

  3. 1394-Minimum Inversion Number

    Minimum Inversion Number Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java ...

  4. HDU 1394Minimum Inversion Number(线段树)

    题目大意是说给你一个数组(N个),没戏可以将其首部的k(k<N)个元素移动至尾部,这样总共会形成N个序列 现在要求这n个序列中逆序对数最少的那一个序列有多少个逆序对 最初的确是没太多思路,就算知 ...

  5. HDU 1394-Minimum Inversion Number(BIT)

    题意: 给你n个数字的序列 每次把第一个数字放到最后 得到一个新序列 一共有n个序列求这些序列中哪个序列含最小的总的逆序数 (输出最小总逆序数) 分析: 用BIT求出初始各数的逆序数,第一个数放最后它 ...

  6. HDU 1394 Minimum Inversion Number ( 树状数组求逆序数 )

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 Minimum Inversion Number                         ...

  7. HDU 1394 Minimum Inversion Number(最小逆序数 线段树)

    Minimum Inversion Number [题目链接]Minimum Inversion Number [题目类型]最小逆序数 线段树 &题意: 求一个数列经过n次变换得到的数列其中的 ...

  8. HDU 1394 Minimum Inversion Number(最小逆序数/暴力 线段树 树状数组 归并排序)

    题目链接: 传送门 Minimum Inversion Number Time Limit: 1000MS     Memory Limit: 32768 K Description The inve ...

  9. ACM Minimum Inversion Number 解题报告 -线段树

    C - Minimum Inversion Number Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d &a ...

  10. HDU-Minimum Inversion Number(最小逆序数)

    Problem Description The inversion number of a given number sequence a1, a2, ..., an is the number of ...

随机推荐

  1. 《Windows核心编程》第七章——进程优先级实验

    其实就是做个实验,看看SetPriorityClass是否真的会生效. 设计思路:主线程一直在进行某种操作(这里是写文件操作),以保证有一定的CPU占用率:生成的子线程来接收你的命令,决定将进程改变为 ...

  2. 我所遭遇过的游戏中间件---nvDXTLib

    我所遭遇过的游戏中间件---nvDXTLib nvDXTLib是Nvidia提供的一套用于DXT纹理压缩SDK.接口十分简洁,就是提供了几个纹理压缩的函数,其中我使用最多的函数是: DXTLIB_AP ...

  3. strtok()函数

    strtok()这个函数大家都应该碰到过,但好像总有些问题, 这里着重讲下它 首先看下MSDN上的解释: char *strtok( char *strToken, const char *strDe ...

  4. libjson 编译和使用 - 2. 配置使用lib文件

    以下转自:http://blog.csdn.net/laogong5i0/article/details/8223448 1. 在之前的libjson所在的解决方案里新建一个控制台应用程序,叫Test ...

  5. html 制作复杂table

    数据分析,一般都需要显示数据,就需要使用html做复杂的表格.复杂表格一般是对td的rowspan .colspan属性值. 在html中<td> 标签定义 HTML 表格中的标准单元格. ...

  6. 10个最好的 jQuery 视频插件

    在这篇文章中已经收集了10个最佳的jQuery视频插件,帮助开发人员容易地实现网站播放影片功能.可以显示视频和视频播放列表. 1. Bigvideo.js BigVideo.js 是一个jQuery插 ...

  7. UVA 12487 Midnight Cowboy(LCA+大YY)(好题)

    题目pdf:http://acm.bnu.edu.cn/v3/external/124/12487.pdf 大致题意: 一棵树,一个人从A节点出发,等可能的选不论什么一条边走,有两个节点B,C求这个人 ...

  8. Android -- 拷贝assets下的资源文件到SD卡中(可以超过1M)

    很多手机游戏,在安装APK之后都得需要下载相应的资源包,然后才能进入游戏. 有这样一个需求:就是游戏中需要的资源包打在APK内,随apk一起进行安装到手机中. 这样就不需要,在安装APK之后,去下载资 ...

  9. Back Track 5 之 网络踩点(二)

    操作系统探测 Xprobe2 通过ICMP协议来获得指纹,通过模糊矩阵统计分析主动探测数据包对应的ICMP数据特征,进而探测得到远端操作系统的类型. 格式: ./xprobe2 域名 ./xprobe ...

  10. 解决 ASP.NET 编辑错误"CS0006: 未能找到元数据文件C:\WINDOWS\assembly\GAC_32\System.EnterpriseServices\2.0.0.0__b03f5f7f11d50a3a\System.EnterpriseServices.dll"

    问题背景: 公司最近给我配置了一台新Windows 7旗舰版的电脑,这几天一直在迁移文件,因为新电脑上安装Sqlserver r2失败,解决方法是要安装一个800+MB的安装包 由于最近手上事情比较多 ...