您的位置:首页 > 其它

poj 3590 The shuffle Problem

2012-09-15 19:06 477 查看
这是一道置换+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
,factor );
printf( "%d",Lcm
);
sort( factor , factor + ct );
Print( n , ct , factor );
}
}
//system( "pause" );
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: