permutation
来源:互联网 发布:php 微信开发 编辑:程序博客网 时间:2024/05/18 02:58
首先分析题意,在1--n的全排列中,如1 3 4 5 2 ,循环顺序是{1},{3 4 5 2},标准顺序就是{1}{5 2 3 4},去掉括号,此时的排列与原来的排列不同,所以这种排列不是可行排列,可以证明每一个可行排列中,只能是初始排列中(1-n的排列)相邻的两个数字交换位置
证明 假设初始排列 1 2 3 4...x y....n
如果交换x和y的位置 1 2 3... y x....n,该序列循环的排序1 2 3。。{y x}。。n和原序列一样,是可行排列,那么交换其他位置是类似的,只要是两个就是合法的
1 2 3.。x y z ..n 如果三个数位置互换 y z x或z x y。。不管怎么换,循环的排序应该是z开头,那么合法的换法只剩下z x y 而此时循环顺序是z y x,显然不合法
如果中间隔一个数交换位置,x和z,那么循环重新排序后yzx,y的位置会比原序列靠前
打表可以发现,每一块序列(都存在相同的位置改变)的个数是斐波那契数列,而每一块固定都变换过的位置,后面的部分细分之后也是斐波那契数列,只是多了一个fib[0]=1,代表没有交换
#include<iostream>#include<cstdio>#include<cstring>#define LL long longusing namespace std;int n;LL k;LL f[95];bool vis[60];inline void pre(){ f[0]=f[1]=f[2]=1; for(int i=3;i<=90;i++) f[i]=f[i-1]+f[i-2];}int main(){ scanf("%d%lld",&n,&k); pre(); int op=0,m=n; while(k>1){ for(int i=0;i<=90;i++) if(k-f[i]<=0){ if(i!=0) vis[op+m-i]=vis[op+m-i+1]=1; break; } else k-=f[i]; op+=2; m-=2; } for(int i=1;i<=n;i++) if(vis[i]==1&&vis[i+1]==1){ printf("%d %d ",i+1,i); i+=1; } else printf("%d ",i); return 0;}
阅读全文
1 0
- Permutation
- Permutation
- permutation
- Permutation
- Permutation
- Permutation
- permutation
- Permutation
- permutation
- Permutation
- Permutation
- permutation
- permutation
- permutation
- Permutation, next Permutation, Permutation sequence
- Complete Permutation
- 排列(Permutation)
- exercise permutation
- js反转字符串方法
- 使用ImageLoader实例 进行加载图片
- 难忘的JS传参问题
- 用二维数组写的简单的推箱子,一个人,两个箱子,两个圈的情况。。
- HDU2643 Rank 第二类斯特林数
- permutation
- jsp基础—1
- java System类
- Java中的泛型
- 可变参列表
- 集成springmvc和mybatis环境的Javaweb基础框架,省去新手搭建繁琐环境的苦恼
- Kruskal算法:贪心+并查集=最小生成树
- Open-falcon:Agent源码
- 用zookeeper体验监听服务器是否还活着