zoukankan      html  css  js  c++  java
  • 《训练指南》——7.30

      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
    ",dp[n][k]);
    
         
    
     
    
    }
  • 相关阅读:
    RCU介绍
    采用dlopen、dlsym、dlclose加载动态链接库
    linux获取系统启动时间
    Linux获取进程执行时间
    linux下获取硬盘使用情况
    linux下判断文件和目录是否存在
    孤儿进程与僵尸进程
    多个文件目录下Makefile的写法
    System V 共享内存区
    Posix共享内存区
  • 原文地址:https://www.cnblogs.com/rhythmic/p/5721675.html
Copyright © 2011-2022 走看看