排列
来源:互联网 发布:医用冷藏箱知乎 编辑:程序博客网 时间:2024/04/28 18:53
题目描述
一个关于n个元素的排列是指一个从{1, 2, …, n}到{1, 2, …, n}的一一映射的函数。这个排列p的秩是指最小的k,使得对于所有的i = 1, 2, …, n,都有p(p(…p(i)…)) = i(其中,p一共出现了k次)。
例如,对于一个三个元素的排列p(1) = 3, p(2) = 2, p(3) = 1,它的秩是2,因为p(p(1)) = 1, p(p(2)) = 2, p(p(3)) = 3。
给定一个n,我们希望从n!个排列中,找出一个拥有最大秩的排列。例如,对于n=5,它能达到最大秩为6,这个排列是p(1) = 4, p(2) = 5, p(3) = 2, p(4) = 1, p(5) = 3。
当我们有多个排列能得到这个最大的秩的时候,我们希望你求出字典序最小的那个排列。对于n个元素的排列,排列p的字典序比排列r小的意思是:存在一个整数i,使得对于所有j < i,都有p(j) = r(j),同时p(i) < r(i)。对于5来说,秩最大而且字典序最小的排列为:p(1) = 2, p(2) = 1, p(3) = 4, p(4) = 5, p(5) = 3。
N<=10000
DP
首先,几个显然的结论
1、答案所代表的意义为把N分解成若干份能得到这些份的乘积最大值。
2、一些大于1的数的乘积大于它们的和
3、任意两份互质
4、得到方案后,输出排列的最优方案:把份从小到大排序,然后把N个数按照排列后分割,每份转一下。例如
n=14,最优是拆成3+4+7,排序后就是3、4、7
那么第一份割三个即1、2、3,转一下变成2、3、1
第二份割四个即4、5、6、7,转一下变成5、6、7、4
剩下同理。
我们设f[i,j]表示当前做到第i个质数,现在和为j,能得到的最大积。
转移显然,见代码。
由于f数组存的值可能很大,而最后我们并不需要输出答案(只需要输出最优排列),所以可以用自然对数优化:
注意到a*b=c,对应ln(a)+ln(b)=ln(c)
用pre[i,j]表示状态f[i,j]的最优解从哪个状态转移过来。
参考程序
#include<cstdio>#include<algorithm>#include<cmath>#include<iostream>#define fo(i,a,b) for(i=a;i<=b;i++)#define fd(i,a,b) for(i=a;i>=b;i--)using namespace std;typedef double db;db f[1300+10][10000+10],ans,wdc;int pre[1300+10][10000+10],pri[1300+10],a[10000+10];bool bz[10000+10];int i,j,k,l,t,n,m,ca,top,tot;int main(){ top=0; fo(i,2,10000){ if (!bz[i]) pri[++top]=i; fo(j,2,10000/i) bz[i*j]=1; } fo(i,0,top) fo(j,0,10000) pre[i][j]=f[i][j]=0; fo(i,1,top){ fo(j,0,10000){ f[i][j]=f[i-1][j]; pre[i][j]=j; t=pri[i]; while (t<=j){ wdc=f[i-1][j-t]+log(t); if (wdc>f[i][j]){ f[i][j]=wdc; pre[i][j]=j-t; } t*=pri[i]; } } } scanf("%d",&ca); while (ca--){ scanf("%d",&n); ans=0; fo(i,0,n) if (f[top][i]>ans) ans=f[top][i],k=i; tot=0;i=1; while (n-->k) printf("%d ",i++); fd(j,top,1){ t=k-pre[j][k]; if (t) a[++tot]=t; k=pre[j][k]; } sort(a+1,a+tot+1); fo(j,1,tot){ fo(k,i+1,i+a[j]-1) printf("%d ",k); printf("%d ",i); i+=a[j]; } printf("\n"); }}
- 排列
- 排列
- 排列
- 排列
- 排列
- 排列
- 排列
- 排列
- 排列
- 排列
- 排列
- 排列
- 排列
- 排列
- 排列
- 排列
- 排列
- 排列
- Windows电脑上安装Pygame
- Word
- ]MATLAB中的wavedec、wrcoef函数简析
- openjudge avoid the lakes
- <代码之髓>读后感
- 排列
- Vim 相关设置
- 【设计模式】何为设计模式
- cookie和session的区别及用法(PHP5)
- Android高仿网易新闻客户端之动态添加标签
- 25、静态查找表(顺序表、索引顺序表、静态树表、折半查找) http://blog.163.com/zhoumhan_0351/blog/static/39954227200993093110226
- Golang中的管道channel在几个典型语言中的实现
- Failed to find: com.android.support:appcompat-v7:22.0.0报错解决
- 【Java】斐波那契数列前N项(堆栈算法)