HDU1394最小逆序数
来源:互联网 发布:淘宝万斯正品店 编辑:程序博客网 时间:2024/04/28 00:56
层层优化,请往下看(按照编程复杂度排名)
1.暴力 250ms
#include<stdio.h>int a[5003];int main(){ int n, i, j, sum; while (scanf("%d", &n) != EOF) { sum = 0; for (i = 1; i <= n; i++) { scanf("%d", a + i); for (j = 1; j < i; j++) if (a[j] > a[i]) sum++; } int ans = sum; for (i = 1; i <= n; i++) { sum += (-a[i] + n - a[i] - 1); //公式:第一个数移到最后位置后逆序数 //sum=sum+(-low[a[i]]+up[a[i]]) //在0-(n-1)序列里low[a[i]]=a[i],up[a[i]]=n-a[i]+1; if (sum < ans) ans = sum; } printf("%d\n", ans); }}
2、记忆优化 62ms
#include<stdio.h>int a[5003];int main(){ //freopen("//home//amb//桌面//1.in","r",stdin); int n, i, j, sum; while (scanf("%d", &n) != EOF) { sum = 0; bool chu[5003]={0};//已经出来的记录一下 for(i=0;i<=n;i++) { chu[i]=1; } for (i = 1; i <= n; i++) { scanf("%d", &a[i]); chu[a[i]]=0; for(j=0;j<a[i];j++) sum+=chu[j]; } // printf("%d\n", sum); int ans = sum; for (i = 1; i <= n; i++) { sum += (-a[i] + n - a[i] - 1); //公式:第一个数移到最后位置后逆序数 //sum=sum+(-low[a[i]]+up[a[i]]) //在0-(n-1)序列里low[a[i]]=a[i],up[a[i]]=n-a[i]+1; if (sum < ans) ans = sum; } printf("%d\n", ans); }}3、树状数组优化31ms
#define DeBUG#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <algorithm>#include <vector>#include <stack>#include <queue>#include <string>#include <set>#include <sstream>#include <map>#include <bitset>using namespace std ;#define zero {0}#define INF 2000000000#define EPS 1e-6typedef long long LL;const double PI = acos(-1.0);//#pragma comment(linker, "/STACK:102400000,102400000")inline int sgn(double x){ return fabs(x) < EPS ? 0 : (x < 0 ? -1 : 1);}int a[5003];int chu[5003] = {0};int n;int lowbit(int x){ return (x & (-x));}void add(int i, int num){ while (i <= n) { chu[i] += num; i += lowbit(i); }}int Sum(int x){ int sum = 0; while (x > 0) { sum += chu[x]; x -= lowbit(x); } return sum;}int main(){ // freopen("//home//amb//桌面//1.in", "r", stdin); while (scanf("%d", &n) + 1) { memset(chu, 0, sizeof(chu)); int sum = 0; for (int i = 1; i <= n; i++) { add(i, 1); } int k; for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); add(a[i]+1, -1); sum += Sum(a[i]+1); } // printf("%d\n", sum); int ans = sum; for (int i = 1; i <= n; i++) { sum += (-a[i] + n - a[i] - 1); //公式:第一个数移到最后位置后逆序数 //sum=sum+(-low[a[i]]+up[a[i]]) //在0-(n-1)序列里low[a[i]]=a[i],up[a[i]]=n-a[i]+1; if (sum < ans) ans = sum; } printf("%d\n", ans); }}
4、线段树优化 46ms
#define DeBUG#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <cstdlib>#include <algorithm>#include <vector>#include <stack>#include <queue>#include <string>#include <set>#include <sstream>#include <map>#include <bitset>using namespace std ;#define zero {0}#define INF 2000000000#define EPS 1e-6typedef long long LL;const double PI = acos(-1.0);//#pragma comment(linker, "/STACK:102400000,102400000")inline int sgn(double x){return fabs(x) < EPS ? 0 :(x < 0 ? -1 : 1);}#define LL(x) ((x)<<1) #define RR(x) ((x)<<1|1) //twice+1struct Seg_Tree{ int left,right,val; int calmid() { return (left+right)/2; }}tt[15000];int val[5001];void build(int left,int right,int idx){ tt[idx].left=left; tt[idx].right=right; tt[idx].val=0; if(left==right) return ; int mid=tt[idx].calmid(); build(left,mid,LL(idx)); build(mid+1,right,RR(idx));}int query(int left,int right,int idx){ if(left==tt[idx].left&&right==tt[idx].right) return tt[idx].val; int mid=tt[idx].calmid(); if(right<=mid) { return query(left,right,LL(idx)); } else if(mid<left) { return query(left,right,RR(idx)); } else { return query(left,mid,LL(idx))+query(mid+1,right,RR(idx)); }}void update(int id,int idx){ tt[idx].val++; if(tt[idx].left==tt[idx].right) return ; int mid=tt[idx].calmid(); if(id<=mid) { update(id,LL(idx)); } else { update(id,RR(idx)); }}int main(){ #ifdef DeBUGs freopen("//home//amb//桌面//1.in","r",stdin); #endif int n; while(scanf("%d",&n)+1) { build(0,n-1,1); int sum=0; for(int i=0;i<n;i++) { scanf("%d",&val[i]); sum+=query(val[i],n-1,1); update(val[i],1); } int ret=sum; for(int i=0;i<n;i++) { sum=sum-val[i]+(n-val[i]-1); ret=min(ret,sum); } printf("%d\n", ret); } return 0;}
5、优化得好一些的线段树 31ms
#include <iostream>#include <cstdio>#include <cstdlib>#define M 5010using namespace std;int n, map[M], minn, tmp, ans;struct TREE{ int l, r, sum; //区间内已插入的节点数} T[M << 2];void create(int u, int l, int r){ T[u].l = l; T[u].r = r; if (T[u].l == T[u].r) { T[u].sum = 0; return; } int mid = (T[u].l + T[u].r) >> 1; create(u << 1, l, mid); create(u << 1 | 1, mid + 1, r); T[u].sum = T[u << 1].sum + T[u << 1 | 1].sum;}void query(int u, int l, int r){ if (T[u].l >= l && T[u].r <= r) { tmp += T[u].sum; return; } int mid = (T[u].l + T[u].r) >> 1; if (r <= mid) query(u << 1, l, r); else if (l >= mid + 1) query(u << 1 | 1, l, r); else { query(u << 1, l, mid); query(u << 1 | 1, mid + 1, r); }}void updata(int u, int pos){ if (T[u].l == T[u].r) { T[u].sum++; return; } int mid = (T[u].l + T[u].r) >> 1; if (pos <= mid) updata(u << 1, pos); else updata(u << 1 | 1, pos); T[u].sum = T[u << 1].sum + T[u << 1 | 1].sum;}int main(){ while (scanf("%d", &n) != EOF) { minn = 0; for (int i = 1; i <= n; i++) { scanf("%d", &map[i]); map[i]++;//避免0的出现 } create(1, 1, n); for (int i = 1; i <= n; i++) { tmp = 0; if (map[i] + 1 <= n) query(1, map[i] + 1, n); minn += tmp; updata(1, map[i]); } ans = 9999999; for (int i = 1; i <= n; i++) { minn = minn - (map[i] - 1) + n - 1 - (map[i] - 1); //我们曾经把所有的数字都加过1,所以要减去 ans = min(ans, minn); } printf("%d\n", ans); } return 0;}
0 0
- HDU1394最小逆序数
- hdu1394求最小逆序数
- hdu1394 求最小逆序数
- hdu1394 线段树求最小逆序数
- hdu1394 Minimum Inversion Number(最小逆序数)
- hdu1394求逆序数
- hdu1394 逆序数?
- HDU1394 求逆序数
- hdu1394(求逆序数)
- HDU1394(最小逆序数)-线段树单点更新
- HDU1394-Minimum Inversion Number-归并排序求最小逆序数
- hdu1394(最小逆序数)(线段树单点更新)
- hdu1394最小逆序数——线段树
- hdu1394 逆序数-线段树
- hdu1394 Inversion后的最小逆序数 线段树 树状数组
- hdu1394 Minimum Inversion Number 最小逆序数 线段树单点更新区间查询
- hdu1394求最小逆序----树状数组解决
- 线段树求逆序数 hdu1394
- MFC listCtrl选中某一项,LIST失去焦点时,该项仍然显示高亮
- SQL Server应用模式之OLTP系统性能分析
- Android - 布局(layout) 详解
- ubuntu 忘记密码
- Lock与synchronized 的区别
- HDU1394最小逆序数
- 达芬奇ICETEK-DM6446-EVMS中xdcpaths.mak
- 给定一个整数N,求N!末尾有多少个0?N!的二进制表示中最低1的位置?
- ubuntu手动安装grub
- 强引用与弱引用(不太懂,不过文章形容的不错)
- poj3693 ,spoj687 重复次数最多的连续重复子串 后缀数组
- 利用SET STATISTICS IO和SET STATISTICS TIME 优化SQL Server查询性能
- Android ViewPager使用详解
- openssl TXT_DB error number 二 failed to update database