一天一道算法题---6.6---排列递推(我不会)
感谢微信平台: 一天一道算法题-----每天多一点进步——-
好吧 这题 我看了它的分析 还是感觉很不清晰 自己的思路 闪过 逆序数 但也不行,,,
把题目 先放上来
problem:
列出一个 1~n 的排列 可以通过一系列的交换得到(1,2,3……n)比如,{2,1,4,3}需要两次交换(1和2 3和4),(4,2,3,1)需要一次(4和1);
给定n和k 统计有多少个排列至少需要K次交换能变成(1,2,3……n);
各位 大神 不要吝啬 留下你们的思路与想法 告知我 thanks...
感谢楼下提供的代码 和 精彩的分析:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 using namespace std; 3 4 int count(int n, int k) 5 { 6 /* 一个序列最多只需要n-1次交换即可变成1,2,3,...,n的形式,所以n必定>=k+1 */ 7 if(n <= k || k==0 ) 8 return 0; 9 /* 如果一个序列经过1次交换就变回来,那反过来想,就是把1,2,3,...n随便抽取两个交换一下就得到这个序列了,所以一共有 n*(n-1)/2种可能 */ 10 else if(k==1) 11 return n*(n-1)/2; 12 /* 13 如果一个序列经过k次交换变回来,这时候考虑最大数字n所在的位置。如果n在前面 1~n-1个位置,那么最后一个数字必定不是n,假设是i, 14 那么把n和i交换一下,剩下的数字需要经过k-1次交换才能变成1,2,3,...,n-1的形式,所以这种情况共 (n-1)*count(n-1, k-1) 种; 15 如果n在最后一个位置,那显然只需要考虑前面n-1个数字的交换,因此共有count(n-1, k)种。两种情况加起来就是结果 16 */ 17 else 18 return (n-1) * count(n-1, k-1) + count(n-1, k); 19 } 20 21 int main() 22 { 23 int n , k; 24 while( ~scanf("%d %d",&n,&k) ) 25 { 26 printf( "%d\n",count(n,k) ); 27 } 28 return 0; 29 } 30 31 32 33 34 /* 35 test: ------> 1 2 3 4 36 1 2 4 3 37 1 3 2 4 38 1 3 4 2 39 1 4 2 3 40 1 4 3 2 41 2 1 3 4 42 2 1 4 3 43 2 3 1 4 44 2 3 4 1 45 2 4 1 3 46 2 4 3 1 47 3 1 2 4 48 3 1 4 2 49 3 2 1 4 50 3 2 4 1 51 3 4 1 2 52 3 4 2 1 53 4 1 2 3 54 4 1 3 2 55 4 2 1 3 56 4 2 3 1 57 4 3 1 2 58 4 3 2 1 59 */
今天 信神告诉我 那些话 他很喜欢(信神 肯定 动情了 对某个姑凉)
today:
我多麼想和你见一面
看看你最近改变不再需说从前
只是寒暄对你说一句
只是说一句
好久不见
just follow your heart