poj 3590 The shuffle Problem

这是一道置换+DP的的题目;

题意是要你把每一个置换都可以分解成若干个轮换,那么这些轮换的阶的最小公倍数就是该置换的阶。

这里要我们求怎样分解使最小公倍数最大,并且使置换排序最小;

怎样求最大的最小的公倍数,这里我们用DP的方法可以容易求出;dp[i][j]表示i分解成j个数;

排序就只要对因子进行排序就可以了(自己写一下就知道了)在进行输出;

View Code
#include<iostream>
 #include<cstdio>
 #include<cstdlib>
 #include<algorithm>
 #include<cmath>
 #include<queue>
 #include<set>
 #include<map>
 #include<cstring>
 #include<vector>
 #include<string>
 using namespace std;
 int prime[30],cnt=0;
 void Prime( )
 {
      int i ,k;
      for( k = 2 ; k <= 100; k ++ )
      {
          for( i = 2 ; i < k  ; i ++ )
              if( k % i == 0 ) break;
         if( i == k ) 
         prime[cnt++] = k;    
      }
 }
 int Gcd( int a , int b )
 {
    return b ==0 ?  a : Gcd( b , a % b );    
 }
 void Get_Lcm( int Lcm[] )
 {
      int dp[124][124];
      memset( dp , 0, sizeof( dp ) );
      for( int i = 1; i <= 100; i ++ )
           dp[i][1] = i;
      for( int i = 2 ; i <= 100; i ++ )
      {
          for( int j = 2 ; j <= i ; j ++ )
          {
              for( int k = 1 ; (k < i) && (i - k >= j -1) ; k ++ )
              {
                   dp[i][j] = max( dp[i][j] , dp[i-k][j-1]*k/Gcd( dp[i-k][j-1],k ) ); 
              }        
          }        
      }
      for( int i = 1; i <= 100; i ++ )
      {
           Lcm[i] = 0;
           for( int j = 1 ; j <= i; j++ )
               Lcm[i] = max( Lcm[i] , dp[i][j] ); 
      }    
 }
 int Get_factor( int num , int factor[] )
 {
     int ct = 0;
       for( int i = 0 ; i < cnt; i ++ )
       {
          if( num % prime[i]==0 )
          {             
              factor[ct] = 1;
              while( num % prime[i] ==0 )
              {
                     factor[ct] *= prime[i];
                     num /= prime[i];        
              }        
              ct++;
             }    
     }
     return ct;
 }
 void Print( int num, int ct, int factor[]  )
 {
      int sum = 0;
      for( int i = 0 ; i < ct; i ++ )
      sum += factor[i];
      for( int i = 1; i <= num - sum; i ++ )
           printf( " %d",i );    
      int k = num - sum;
      for( int i = 0 ; i < ct ; i ++ )
      {
          for( int j = 2 ; j <= factor[i] ; j ++  )
               printf( " %d",k+j );
          printf( " %d",k+1 );
          k += factor[i];        
      }
      puts( "" );
 }
 int main(  )
 {
      int T,n;
      int Lcm[124],factor[124];
      Prime( );
      Get_Lcm( Lcm );
      while( scanf( "%d",&T )==1 )
      {
           while( T-- )
           {
                scanf( "%d",&n );
                int ct = Get_factor( Lcm[n] ,factor );
                printf( "%d",Lcm[n] );
                sort( factor , factor + ct );
                Print( n , ct , factor );        
           }        
      }
     //system( "pause" );
     return 0;
 }
 

 

posted @ 2012-09-15 19:06  wutaoKeen  阅读(293)  评论(0)    收藏  举报