zoukankan      html  css  js  c++  java
  • HDU 1394

    题意:给定一个序列,每次将第一个元素放至末尾,求其形成的所有序列中逆序数和最小;

    可利用归并排序求出第一次的逆序数和,在用下面的公式求解最小的逆序数和;

    当然此题暴力也可过。

    如果每次都进行如上操作,那么最多进行n-1次后会与原序列重合;

    这个序列的元素是从0---(n-1),当某个元素位于首位置时,其本身的数值就是后面的逆序个数;

    每次将它移至末尾,原来的逆序即变成了正序,正序变逆;由此可得 sum=sum-a[i]+(n-a[i]-1);

    //归并排序:
    #include<stdio.h> #include<stdlib.h> #include<string.h> #define maxn 5010 #define Min(a,b)(a<b?a:b) int ac[maxn],ak[maxn],temp[maxn],ans; void merger(int *A,int s,int mid,int e) { int i,j,k=0; for(i=s,j=mid+1; i<=mid && j<=e;) { if(A[i] < A[j]) temp[k++]=A[i++]; else { ans+=mid-i+1; temp[k++]=A[j++]; } } while(i<=mid) temp[k++]=A[i++]; while(j<=e) temp[k++]=A[j++]; for(i=0; i<k; i++) A[s+i]=temp[i]; } void mergersort(int *A,int s,int e) { if(s<e) { int mid =(s+e)/2; mergersort(A,s,mid); mergersort(A,mid+1,e); merger(A,s,mid,e); } } int main() { int n,i,sum; while(~scanf("%d",&n)) { for(i=0; i<n; i++) { scanf("%d",&ac[i]); ak[i]=ac[i]; } ans=0; mergersort(ac,0,n-1); sum=ans; for(i=0; i<n; i++) { sum=sum-ak[i]+(n-ak[i]-1); ans=Min(sum,ans); } printf("%d ",ans); } return 0; }
    //暴力解决:
    #include<stdio.h> int a[5005]; int main() { int n,i,j,ans,sum; while(~scanf("%d",&n)) { for(i=0; i<n; i++) scanf("%d",&a[i]); ans = 0; sum=999999999; for(i=0; i<n; i++) for(j=i+1; j<n; j++) if(a[i]>a[j]) ans++; if(ans < sum) sum =ans; for(i=0; i<n; i++) { ans = ans -a[i] +(n-1-a[i]); if(ans < sum) sum =ans; } printf("%d ",sum); } return 0; }
  • 相关阅读:
    poj 3254 Corn Fields 状压dp
    poj 1330 Nearest Common Ancestors LCA/DFS
    poj1182 食物链 带权并查集 偏移量
    ural 1019. Line Painting 线段树 离散化
    zoj 2301 || hdu 1199 Color the Ball 线段树 离散化
    poj 1195 Mobile phones 二维树状数组
    poj 2155 Matrix 二维树状数组
    poj3067 Japan 树状数组 逆序数
    OpenWRT Init (User space boot) reference for Chaos Calmer: procd
    怎样写一个基于procd的init脚本
  • 原文地址:https://www.cnblogs.com/cn-blog-cn/p/4712489.html
Copyright © 2011-2022 走看看