Hdu 1394-Minimum Inversion Number【暴力求解Or线段树Or树状数组】
2015-07-12 18:03
369 查看
Total Submission(s): 13357 Accepted Submission(s): 8167
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
Sample Output
16
//树状数组:46ms[/code]
Minimum Inversion Number
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 13357 Accepted Submission(s): 8167
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
[code]//暴力求解 时间就不说了吧 #include <cstdio> #include <string> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int maxn = 5000+5; int N,arr[maxn]; int main() { // freopen("input.in","r",stdin); while(~scanf("%d",&N)) { for(int i = 0;i < N;i++) { scanf("%d",&arr[i]); } int ans,cnt=0; for(int i = 0;i < N;i++) { for(int j = i+1;j < N;j++) { if(arr[i]>arr[j]) cnt++; } } ans = cnt; for(int i = 0;i < N;i++) { cnt = cnt+(N-1-arr[i])-arr[i];//找出规律,每次将最前面的数移至末尾,大于arr[i]的数为(N-1-arr[i]),小于arr[i]的数为arr[i]. ans = min(ans,cnt); } printf("%d\n",ans); } return 0; }
//树状数组:46ms[/code]
#include <map> #include <cmath> #include <vector> #include <cstdio> #include <string> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 const int maxn = 5000+5; int N,ans,arr[maxn],TreeArr[maxn]; int lowbit(int x) { return x&(-x); } void Add(int pos,int add=1) { while(pos <= N) { TreeArr[pos] += add; pos+=lowbit(pos); } } int Sum(int pos) { int ret = 0; while(pos > 0) { ret+=TreeArr[pos]; pos -= lowbit(pos); } return ret; } int main() { //freopen("input.in","r",stdin); while(~scanf("%d",&N)) { ans = 0;memset(TreeArr,0,sizeof(TreeArr)); for(int i = 1;i <= N;i++) { scanf("%d",&arr[i]);arr[i]++; //将每个数加一,这样就把数控制在1~N范围,貌似看起来舒服些 ans += Sum(N)-Sum(arr[i]); //将之前的数中在区间arr[i]~N的个数进行累加 Add(arr[i]); } for(int i = 1,cnt = ans;i <= N;i++) { cnt += (N-arr[i])-arr[i]+1; ans = min(ans,cnt); } printf("%d\n",ans); } return 0; }
//线段树 93ms #include <vector> #include <cstdio> #include <string> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 const int maxn = 5000+5; int N,ans,arr[maxn],segTree[maxn<<2]; void PushUp(int rt) { segTree[rt] = segTree[rt<<1] + segTree[rt<<1|1]; } void Build(int l,int r,int rt) { segTree[rt] = 0; if(l == r) return ; int mid = l+((r-l)>>1); Build(lson); Build(rson); } void Update(int pos,int l,int r,int rt) { if(l == r) { segTree[rt]++; return ; } int mid = l+((r-l)>>1); if(pos<=mid) Update(pos,lson); else Update(pos,rson); PushUp(rt); } int Query(const int &L,const int &R,int l,int r,int rt) { if(L<=l&&r<=R) { return segTree[rt]; } int mid = l+((r-l)>>1),ret = 0; if(L<=mid) ret+=Query(L,R,lson); if(R>mid) ret+=Query(L,R,rson); return ret; } int main() { // freopen("input.in","r",stdin); while(~scanf("%d",&N)) { ans = 0;Build(1,N,1); for(int i = 0;i < N;i++) { scanf("%d",&arr[i]);arr[i]++; //将每个数加一,这样就把数控制在1~N范围,貌似看起来舒服些 if(arr[i] != N) ans += Query(arr[i]+1,N,1,N,1); //将之前的数中在区间arr[i]+1~N的个数进行累加 Update(arr[i],1,N,1); } for(int i = 0,cnt = ans;i < N;i++) { cnt += (N-arr[i])-arr[i]+1; ans = min(ans,cnt); } printf("%d\n",ans); } return 0; }当然,我还在网上看到了有用归并排序模板过的,这里就不累赘了!转载请注明出处,谢谢!~
相关文章推荐
- html5 css3中的一些笔记
- linux下mysql远程链接
- 【NHibernate】应用层面需要掌握的知识汇总
- 在java中,什么叫接口?
- ViewPager与PagerAdapter(PagerAdapter工作流程)
- 【Caffe】训练ImageNet模型
- Remove Linked List Elements (leetcode 203)
- GObject对象系统
- C++类型转换之static_cast, dynamic_cast, reinterpret_cast, const_cast探讨
- 手把手教你:python字符串编码详解
- 关于@PostConstruct不起作用,以及context:component-scan父子容器,事务失败
- 硬链接和软链接的区别和作用
- Isomorphic Strings -- leetcode
- 软件测试书籍列表
- Java中this用法详解
- poj1376 robot bfs
- Codeforces Round #304 (Div. 2) D - Soldier and Number Game
- Android-70-SQLite出错:no such table: XXXTbl
- 数组-12. 简易连连看
- HTML5学习资源