POJ 3590 The shuffle Problem(置换+DP)
来源:互联网 发布:柯桥法院淘宝拍卖网 编辑:程序博客网 时间:2024/06/08 16:48
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
[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;}
- POJ 3590 The shuffle Problem 置换+DP
- POJ 3590 The shuffle Problem(置换+DP)
- [POJ3590]The shuffle Problem(置换+dp)
- poj 3590 The shuffle Problem (置换+分组背包)
- poj 3590 The shuffle Problem(置换群的幂运算)
- 【POJ 3590】The shuffle Problem
- 置换+DP POJ 3590
- pku 3590 The shuffle Problem
- pku3590 The shuffle Problem
- POJ3590 The shuffle Problem
- poj 2904 The Mailboxes Manufacturers Problem(DP)
- POJ 2282 The Counting Problem (数位dp)
- poj 2282 The Counting Problem (数位DP)
- The Counting Problem - POJ 2282 数位dp
- UVA - 1156 Pixel Shuffle (置换+模拟)
- poj 2282 The Counting Problem && poj 3286 How many 0's? (数位dp)
- UVA Find the Permutations 11077 (DP&置换群)
- HDU 5445 Food Problem、UVa 10163 Storage Keepers、POJ 3260 The Fewest Coins(两次dp)
- oj网站的训练题
- java执行cmd命令并获取返回结果字符串
- 中秋#2 OpenCup_10353
- linux启动过程详解
- U3D网格解决方案
- POJ 3590 The shuffle Problem(置换+DP)
- GYM 2017 ACM Amman Collegiate Programming Contest
- 数据结构——链表之有序链表的归并
- [双联通分量 并查集] CEOI 2017. One-Way Streets
- 排序算法之选择排序
- 软件的生命周期及其模型
- Eclipse自动提示报错,反应慢(alt + 斜杠)
- 数据结构——链表之单链表的拆分
- 增量和减量运算符: ++和--