博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UVA11077 Find the Permutations —— 置换、第一类斯特林数
阅读量:4467 次
发布时间:2019-06-08

本文共 1187 字,大约阅读时间需要 3 分钟。

题目链接:

 

题意:

问n的全排列中多有少个至少需要交换k次才能变成{1,2,3……n}。

 

题解:

1.根据过程的互逆性,可直接求{1,2,3……n}至少需要交换多少次才能变成{a1,a2,a3……an},因此可直接把{a1,a2,a3……an}看成是{1,2,3……n}的置换。为什么呢?

答:1 2 3

  2 3 1  可知把“2 3 1”看作是经过置换后的序列,则:2-->1(2放到1)、3-->2(3放到2)、1-->3(1放到3)。

         把“2 3 1”看作是置换,                        则:1-->2(1放到2)、2-->3(2放到3)、3-->1(3放到1)。

所以把序列看成是置换的话,那么它与变成自己的置换的形状完全相同,只是所有箭头的方向都发生了改变。

2.将一个置换分解成若干个循环,对于一个长度为len的循环,需要交换len-1次才能使得里面的每一个元素回到自己的位置(每一次交换都能使得一个元素回到原来的位置,一直交换到最后一个,就直接在自己的位置上。所以位len-1)。

3.根据第二点,即有多少个循环,就能减少多少次交换。而交换了k次,即减少了n-k交换,因此也就有n-k个循环。把n个有区别的元素排列成n-k个循环(圈),即为第一类斯特林数。

 

代码如下:

1 #include 
2 #include
3 #include
4 #include
5 #include
6 #include
7 #include
8 #include
9 #include
10 #include
11 #include
12 using namespace std;13 typedef long long LL;14 const int INF = 2e9;15 const LL LNF = 9e18;16 const int MOD = 1e9+7;17 const int MAXN = 30;18 19 unsigned long long dp[MAXN][MAXN];20 void init()21 {22 memset(dp, 0, sizeof(dp));23 for(int i = 1; i<=21; i++) //第一类斯特林数24 {25 dp[i][0] = 0; dp[i][i] = 1;26 for(int j = 1; j
View Code

 

转载于:https://www.cnblogs.com/DOLFAMINGO/p/8526327.html

你可能感兴趣的文章
Asp.net MVC入门视频教程
查看>>
[Web前端系列之_Firebug_00_序]
查看>>
用NPOI完成公司任务(主要就是导入导出操作)
查看>>
Cracking the Coding Interview Q1.1
查看>>
汇编指令解释大全【转载】
查看>>
MySQL5.6.11安装步骤(Windows7 64位)
查看>>
使用Batch批量添加数据
查看>>
性能分析方法
查看>>
Solution for XPROG-M Unknown command Software error
查看>>
php--isset()、is_null() 、empty()
查看>>
ES与CQRS之旅
查看>>
[RabbitMQ]Windows环境下rabbitmqclt(Command Line Tools)出现Erlang distribution failed错误的解决方法...
查看>>
C#设计模式(14)——模板方法模式(Template Method)
查看>>
《集体智慧编程》读书笔记3
查看>>
HomeBrew
查看>>
数据类型和变量
查看>>
TEST framework(1)
查看>>
数据库为什么要用B+树结构--MySQL索引结构的实现
查看>>
第六章 总线
查看>>
UNIX和类UNIX操作系统
查看>>