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'; } }