zoukankan      html  css  js  c++  java
  • HDU1394 Minimum Inversion Number

      题目:给定一个数字串0 - N-1,每次可以移动首位数字到末尾,求最少的逆序对的组合方式。先求出原序列的逆序对,再用数学公式算出最佳值。

      假设有 10 个数,依题义为 0 - 9,那么首位为4的话,从首位移动到末尾产生新的逆序对为0 - 9中大于4的数字减去少于4的数。

      代码如下:

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    using namespace std;
    
    int N, num[5005];
    
    void getint( int &t )
    {
    	char c;
    	while( c= getchar(), c< '0'|| c> '9' ) ;
    	t= c- '0';
    	while( c= getchar(), c>= '0'&& c<= '9' )
    	{
    		t= t* 10+ c- '0';
    	}
    }
    
    inline int get( int x )
    {
    	return N- 1- 2* x;
    }
    
    int main()
    {
    	while( scanf( "%d", &N )!= EOF )
    	{ 
    	    int cnt= 0;
    		for( int i= 1; i<= N; ++i )
    		{
    		    getint( num[i] );
    		    for( int j= 1; j< i; ++j )
    		    {
    		        if( num[i]< num[j] )
    		        {
    		            cnt++;
    		        }
    		    }
    		}
    		int min= cnt, temp= cnt;
    		for( int i= 1; i<= N; ++i )
    		{
    		    temp+= get( num[i] );
    		    if( temp< min )
    		    {
    		        min= temp;
    		    }
    		}
    		printf( "%d\n", min );
    	}
    }
    

      

      下面的写法为线段树版,为什么要用线段树呢,注意上面的程序,在求逆序对的时候,我们都是暴力的遍历。现假设前面的数据中出现了某一区间的数都已经出现了,那么后面的数小于该区间的话,就可以之间处理了,不用一个一个的去比较,更像是把原先无序的数字,经过线段树变得具有一定的结构,便于后面的查询。

      代码如下:

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    using namespace std;
    
    int N, rec[5005];
    
    struct Node
    {
    	int l, r, cnt;
    }t[15005];
    
    void creat( int p, int l, int r )
    {
    	t[p].l= l, t[p].r= r;
    	t[p].cnt= 0; // 在创建一棵线段树的时候每个节点都应将所衔的数置零
    	if( r- l> 1 )
    	{
    		creat( p<< 1, l, ( l+ r )>> 1 );
    		creat( ( p<< 1 )+ 1, ( l+ r )>> 1, r );
    	}
    }
    
    void update( int p, int l, int r, int &temp )
    { // 更新得到逆序对的最新数据
    	if( t[p].l== l&&t[p].r== r )
    	{
    		temp+= t[p].cnt;
    		return;
    	}
    	int mid= ( t[p].l+ t[p].r )>> 1;
    	if( l>= mid )
    	{
    		update( ( p<< 1 )+ 1, l, r, temp );
    	}
    	else if( r<= mid  )
    	{
    		update( p<< 1, l, r, temp );
    	}
    	else
    	{
    		update( p<< 1, l, mid, temp );
    		update( ( p<< 1 )+ 1, mid, r, temp );
    	}
    }
    
    void add( int p, int pos )  // 添加操作,在经过的区间都加1
    {
    	t[p].cnt++;
    	if( t[p].r- t[p].l== 1 )
    	{
    		return;
    	}
    	else if( pos>= ( t[p].l+ t[p].r )>> 1 )
    	{
    		add( ( p<< 1 )+ 1, pos );
    	}
    	else
    	{
    		add( p<< 1, pos );
    	}
    }
    
    int get( int x )
    {
    	return N- 1- 2* x;
    }
    
    int main(  )
    {
    	while( scanf( "%d", &N )!= EOF )
    	{
    		int min= 0x7fffffff, temp= 0;
    		for( int i= 1; i<= N; ++i )
    		{
    			t[i].cnt= 0;
    		}
    		creat( 1, 0, N+ 1 );  // 从0开始比编号
    		for( int i= 1; i<= N; ++i )
    		{
    			scanf( "%d", &rec[i] );
    			update( 1, rec[i]+ 1, N+ 1, temp ); // 寻找比rec[i]大的数
    			add( 1, rec[i] );
    		}
    		for( int i= 1; i<= N; ++i )
    		{
    			temp+= get( rec[i] );
    			if( temp< min )
    			{
    				min= temp;
    			}
    		}
    		printf( "%d\n", min );
    	}
    }
    

      

  • 相关阅读:
    离开APM的弹性云还是真弹性吗
    系统性能工程师
    How the performance impacts your revenue-性能影响营收
    The Performance Manifesto
    APM系列-国外新兴厂商New Relic vs. AppDynamics
    Performance testing architecture
    Does Little'law really applicable to apply performance model now?
    Load average in Linux的精确含义
    Eric's并发用户数估算与Little定律的等价性
    Sublime Text 3 插件安装及Vim 模式设置
  • 原文地址:https://www.cnblogs.com/Lyush/p/2139869.html
Copyright © 2011-2022 走看看