zoukankan      html  css  js  c++  java
  • UVA11077 循环群计数

     1 /*UVA11077
     2 循环群计数
     3 n个数的排列数P(n)=n!
     4 一个n的排列可以通过两两交换变成一个(123..n)的顺序排列
     5 判断方法我们熟知,把这个排列写生不相交循环,最少操作数d=n-循环群个数x
     6 现在问题求的是多少个n的排列至少通过k次两两交换。
     7 现在逐步分析:
     8 设f(n,k)为n的排列,通过k次最少交换
     9 f(n,k)=f(n-1,k)+f(n-1,k-1)*(n-1)//这点白书上有错误
    10 解释:f(n-1,k-1),循环群个数n-k个,变成f(n,k),不需要新增循环群,将数字n插入前n-1个位置都可
    11 同理,f(n-1,k),循环群个数n-k-1个,变成f(n,k),要新增一个循环群,故n单独成循环群,放置在最后
    12 边界f(i,0)=1;其他为0
    13 注意测试大数字
    14 */
    15 #include<iostream>
    16 #include<stdio.h>
    17 #include<string.h>
    18 #include<algorithm>
    19 #include<stdlib.h>
    20 #include<math.h>
    21 #include<queue>
    22 #include<vector>
    23 #include<map>
    24 #define ULL unsigned long long
    25 using namespace std;
    26 
    27 int n,k;
    28 ULL F[25][25];
    29 void init(){
    30     memset(F,0,sizeof(F));
    31     for(int i=1;i<=21;i++)F[i][0]=1;
    32     for(int i=2;i<=21;i++){
    33         for(int j=1;j<i;j++)
    34             F[i][j]=F[i-1][j-1]*(i-1)+F[i-1][j];
    35     }
    36     return ;
    37 }
    38 int main(){
    39     init();
    40     while(cin>>n>>k ){
    41         if (n==0 && k==0) break;
    42         cout<<F[n][k]<<endl;
    43 
    44     }
    45     return 0;
    46 }
  • 相关阅读:
    Hibernate——openSession和getCurrentSession区别
    Oracle存储过程分页 详解
    如何破解mysql数据库的密码
    Oracle约束详解
    Oracle分页查询
    Oracle如何管理权限和角色
    悲观锁和乐观锁详解
    Oracle控制结构详解
    Rose建模之各模型分析
    div布局中将页面居中的方法
  • 原文地址:https://www.cnblogs.com/little-w/p/3570260.html
Copyright © 2011-2022 走看看