码迷,mamicode.com
首页 > 其他好文 > 详细

《训练指南》——7.30

时间:2016-07-30 21:08:48      阅读:125      评论:0      收藏:0      [点我收藏+]

标签:

  Uva:11077

  给出n和k的值,求解n的全排列中需要变换k次才能变成{1,2,…n}的个数。

  分析:这个题目是很典型的基于组合分析的问题。这里进行k次变换的操作,也称置换操作。举个最简单的例子,{1,2} -> {2,1}完成了一次置换。

  然后结合组合数学中循环节的概念,对于长度为i,置换j次形成{1,2,…i}的排列个数记作dp[i][j],那么我们尝试建立递推关系式。

  考虑dp[i][j]的子问题的情况:

(1)       长度为i-1,如果添加元素i单独形成循环节(也就是将i说加到了长度为i-1的排列的最后),显然此时我们有dp[i-1][j]种方法

(2)       长度为i-1,如果添加的元素i和其他元素形成循环节,即将元素i在前i-1个位置中的一处安置,那么显然我们这里有(i-1)dp[i-1][j-1]种方法。

  简单的参考代码如下:

 

#include<cstdio>

#include<cstring>

 

using namespace std;

const int maxn = 22;

unsigned long long dp[maxn][maxn];

 

int main()

{

     int n , k;

    for(int i = 1; i <= 22;i++)

                dp[i][0] = 1;

 

      for(int i = 2;i <= 22;i++)

           for(int j = 1;j < i;j++)

              dp[i][j] = dp[i-1][j-1]*(i-1) + dp[i - 1][j];

          

 

      while(scanf("%d%d",&n,&k) != EOF)

                printf("%llu\n",dp[n][k]);

     

 

}

 

《训练指南》——7.30

标签:

原文地址:http://www.cnblogs.com/rhythmic/p/5721675.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!