uva11077 Find the Permutations(置换+递推)

https://vjudge.net/problem/UVA-11077

题意:

给定n和k,问有多少n的排列能够通过至少k次交换变成{1,2,3,……n}

 

一个排列P变成{1,2,3,……n}所需的最少交换次数 等于 {1,2,3,……n}变成P所需的最少交换次数

把P理解为一个置换,分解为循环

含c个元素的循环需要交换c-1次

 

设f(i,j)表示至少需要j次交换变成{1,2,……n}的排列个数

元素i要么自己构成循环,要么加入前面任意一个循环的数后面

所以f(i,j)=f(i-1,j)+f(i-1,j-1)*(i-1)

 

#include<bits/stdc++.h>

using namespace std;

unsigned long long f[22][22];

int main()
{
    f[1][0]=1;
    for(int i=2;i<=21;++i)
        for(int j=0;j<i;++j)
        {
            f[i][j]=f[i-1][j];
            if(j) f[i][j]+=f[i-1][j-1]*(i-1);
        }
    int n,k;
    while(scanf("%d%d",&n,&k))
    {
        if(!n && !k) return 0;
        cout<<f[n][k]<<'\n';
    }    
}

 

posted @ 2021-07-30 20:43  TRTTG  阅读(38)  评论(0编辑  收藏  举报