POJ 3590 The shuffle Problem(置换+DP)

来源:互联网 发布:柯桥法院淘宝拍卖网 编辑:程序博客网 时间:2024/06/08 16:48
The shuffle Problem
Time Limit: 3000MS Memory Limit: 65536KTotal Submissions: 2173 Accepted: 723

Description

Any case of shuffling of n cards can be described with a permutation of 1 to n. Thus there are totally n! cases of shuffling. Now suppose there are 5 cards, and a case of shuffle is <5, 3, 2, 1, 4>, then the shuffle will be:

Before shuffling:1, 2, 3, 4, 5
The 1st shuffle:5, 3, 2, 1, 4
The 2nd shuffle:4, 2, 3, 5, 1
The 3rd shuffle:1, 3, 2, 4, 5
The 4th shuffle:5, 2, 3, 1, 4
The 5th shuffle:4, 3, 2, 5, 1
The 6th shuffle:1, 2, 3, 4, 5(the same as it is in the beginning)

You'll find that after six shuffles, the cards' order returns the beginning. In fact, there is always a number m for any case of shuffling that the cards' order returns the beginning after m shuffles. Now your task is to find the shuffle with the largest m. If there is not only one, sort out the one with the smallest order.

Input

The first line of the input is an integer T which indicates the number of test cases. Each test case occupies a line, contains an integer n (1 ≤ n ≤ 100).

Output

Each test case takes a line, with an integer m in the head, following the case of shuffling.
 

Sample Input

215

Sample Output

1 16 2 1 4 5 3

Source

South Central China 2008 hosted by NUDT

[Submit]   [Go Back]   [Status]   [Discuss]

Home Page   Go Back  To top


题意:给你一个n,让你找一个n阶置换,使得置换的字典序最小,且置换的次数尽可能的多。

题解:我们知道,置换是由若干个循环节构成,每个循环节的长度的最小公倍数便是总的置换次数。

并且所有的循环节长度之和为n,呢么题目其实就是让我们找到若干个数x1.....xm使得:

x1+x2+....xm=n && lcm(x1,x2....xm)最大。

对于求最大的lcm,我们考虑dp即可。剩下的循环节直接模拟贪心找就好。

#include<set>      #include<map>         #include<stack>                #include<queue>                #include<vector>        #include<string>     #include<time.h>    #include<math.h>                #include<stdio.h>                #include<iostream>                #include<string.h>                #include<stdlib.h>        #include<algorithm>       #include<functional>        using namespace std;                #define ll long long          #define inf 1000000000         #define mod 1000000007             #define maxn  30   #define lowbit(x) (x&-x)                #define eps 1e-9 ll dp[105],c[105];int a[105]={1,1},b[50],ans[105],cnt;void init(){int i,j;for(i=2;i<=100;i++){if(a[i])continue;b[++cnt]=i;for(j=i*i;j<=100;j+=i)a[j]=1;}}int q(int x,int y){int res=1;while(y){if(y%2)res=res*x;x=x*x;y/=2;}return res;}int main(void){init();int T,n,i,j,k;scanf("%d",&T);while(T--){scanf("%d",&n);for(i=0;i<=100;i++)dp[i]=1,ans[i]=1;for(i=1;i<=cnt;i++){for(j=0;j<=n;j++)c[j]=dp[j];for(j=1;q(b[i],j)<=n;j++){ll tmp=q(b[i],j);for(k=tmp;k<=n;k++)dp[k]=max(dp[k],c[k-tmp]*tmp);}}printf("%lld",dp[n]);int sum=0,num=0;ll mx=dp[n];for(i=1;i<=cnt;i++){int flag=0;while(mx%b[i]==0){flag=1;mx/=b[i];ans[num]*=b[i];}if(flag){sum+=ans[num];num++;}}sort(ans,ans+num);for(i=1;i<=n-sum;i++)printf(" %d",i);int len=n-sum;for(i=0;i<num;i++){for(j=2;j<=ans[i];j++)printf(" %d",len+j);printf(" %d",len+1);len+=ans[i];}printf("\n");}return 0;}


原创粉丝点击