UVa 11077 Find the Permutations(置换+递推)
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=35431
【思路】
置换+递推
将一个排列看作一个置换,分解为k个循环,则最少需要n-k次交换(循环内部交换)即可排序。
设f[i][j]表示将i个数至少交换j次排序完成的方案数,则有转移方程:
f[i][j] = f[i-1][j]+(i-1)*f[i-1][j-1]
分别表示独立成为一个循环与加入前i-1个循环。
【代码】
#include<cstdio> #include<cstring> using namespace std; typedef unsigned long long LL; const int N = 30+5; LL f[N][N]; int n,k; 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] += (i-1)*f[i-1][j-1]; } while(scanf("%d%d",&n,&k)==2 && (n||k)) printf("%llu\n",f[n][k]); return 0; }
posted on 2016-01-14 16:39 hahalidaxin 阅读(191) 评论(0) 编辑 收藏 举报