poj 3590 The shuffle Problem(置换群+DP)
生活随笔
收集整理的這篇文章主要介紹了
poj 3590 The shuffle Problem(置换群+DP)
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
題目鏈接:poj 3590 The shuffle Problem
題意:
給你一個數(shù)n,讓你找一個字典序最小的置換序列,使得變換整個周期最大。
題解:
由于置換群的性質(zhì),我們可以將n拆分成m個數(shù),使得這m個數(shù)的和為n,并且這m個數(shù)的最小公倍數(shù)最大。
dp可以求出將n拆分后的最大的最小公倍數(shù)。
然后可以將這個最大的最小公倍數(shù)分解為pi^mi+pi^mi+pi^mi...。
對于每一個pi^mi,就是一個循環(huán)的輪數(shù)。
然后將這些循環(huán)的輪數(shù)排序后輸出對于的數(shù)字就行了。
PS:當(dāng)前面的總和sum小于n時,前n-sum的循環(huán)輪數(shù)就全是1,這些數(shù)不會影響最大的最小公倍數(shù)。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #define F(i,a,b) for(int i=a;i<=b;++i) 5 using namespace std; 6 typedef long long ll; 7 8 const int N=101; 9 10 int primes[N+1],tot=0; 11 bool vis[N+1]; 12 void Euler(){ 13 memset(vis,0,sizeof(vis)); 14 F(i,2,N){ 15 if(!vis[i])primes[++tot]=i; 16 F(j,1,tot){ 17 if(i*primes[j]>N)break; 18 vis[i*primes[j]]=1; 19 if(i%primes[j]==0)break; 20 } 21 } 22 } 23 24 int dp[N][N],mx[N],cnt,tmp,t,sum,n,ans[N]; 25 26 void init() 27 { 28 F(i,1,100)F(j,1,100)dp[i][1]=i; 29 F(i,1,100) 30 { 31 F(j,1,i) 32 { 33 F(k,1,i-1) 34 { 35 int tmp=dp[i-k][j-1]*k/__gcd(dp[i-k][j-1],k); 36 if(dp[i][j]<tmp)dp[i][j]=tmp; 37 } 38 } 39 F(j,1,i)mx[i]=max(dp[i][j],mx[i]); 40 } 41 } 42 43 int main() 44 { 45 Euler(),init(); 46 scanf("%d",&t); 47 while(t--) 48 { 49 scanf("%d",&n); 50 tmp=mx[n],sum=cnt=0; 51 printf("%d",mx[n]); 52 int tmp=mx[n],tp; 53 F(i,1,25) 54 { 55 if(primes[i]>tmp)break; 56 if(tmp%primes[i]==0) 57 { 58 tp=1; 59 while(tmp%primes[i]==0)tmp/=primes[i],tp*=primes[i]; 60 ans[++cnt]=tp,sum+=tp; 61 } 62 } 63 sort(ans+1,ans+1+cnt); 64 F(i,1,n-sum)printf(" %d",i); 65 int now=1,num=ans[now],ct=0; 66 F(i,n-sum+1,n) 67 { 68 if(ct==num-1) 69 printf(" %d",i-ct),ct=0,num=ans[++now]; 70 else printf(" %d",i+1),ct++; 71 } 72 puts(""); 73 } 74 return 0; 75 } View Code?
轉(zhuǎn)載于:https://www.cnblogs.com/bin-gege/p/7074305.html
總結(jié)
以上是生活随笔為你收集整理的poj 3590 The shuffle Problem(置换群+DP)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MVC之排球比赛计分程序 ——(二)架构
- 下一篇: Java并发编程实战 第13章 显式锁