山东济南彤昌机械科技有限公司 山东济南江鹏工贸游有限公司

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编辑  收藏  举报