一天一道算法题---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...

感谢楼下提供的代码 和 精彩的分析:

 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
",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 */
View Code

今天 信神告诉我 那些话 他很喜欢(信神 肯定 动情了 对某个姑凉)

today:

我多麼想和你见一面
看看你最近改变不再需说从前
只是寒暄对你说一句
只是说一句
好久不见

just follow your heart
原文地址:https://www.cnblogs.com/radical/p/3775500.html