1. 程式人生 > >UVA - 11077 Find the Permutations (置換)

UVA - 11077 Find the Permutations (置換)

ive tinc none unsigned ati 多少 space include spec

Sorting is one of the most usedoperations in real life, where Computer Science comes into act. It iswell-known that the lower bound of swap based sorting is nlog(n).It means that the best possible sorting algorithm will take at least W(nlog(n))swaps to sort a set of nintegers. However, to sort a particular array of n integers, you can alwaysfind a swapping sequence of at most (n-1) swaps, once you know theposition of each element in the sorted sequence. For example – consider fourelements <1 2 3 4>. There are 24 possible permutations and for allelements you know the position in sorted sequence.

If the permutation is <2 1 43>, it will take minimum 2 swaps to make it sorted. If the sequence is<2 3 4 1>, at least 3 swaps are required. The sequence <4 2 31> requires only 1 and the sequence <1 2 3 4> requires none. In thisway, we can find the permutations of Ndistinct integers which will take at least K swaps to be sorted.

Input

Each input consists of two positiveintegers N (1≤N≤21) and K (0≤K<N) in a single line. Inputis terminated by two zeros. There can be at most 250 test cases.

Output

For each of the input, print in aline the number of permutations which will take at least K swaps.

SampleInput Output for Sample Input

3 1

3 0

3 2

0 0

 

3

1

2


Problemsetter: Md. Kamruzzaman

Special Thanks: Abdullah-al-Mahmud

題意:給出一個1-n的排列。能夠通過一系列的置換變成{1,2,3...n},給定n和k。統計有多少個排列須要交換k次才幹變成{1,2,3..n}

思路:我們能夠把排列p理解成一個置換,而且分解成循環,則各循環之間獨立,且c個元素的循環須要交換c-1次,設f[i][j]表示至少須要交換j次才幹變成{1,2....i}的排列個數,則f[i][j] = f[i-1][j] + f[i-1][j-1]*(i-1)。由於元素i要麽自己形成一個循環,要麽增加前兩隨意一個循環的任何位置

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
typedef unsigned long long ull;
using namespace std;
const int maxn = 30;

ull f[maxn][maxn];

int main() {
	memset(f, 0, sizeof(f));
	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) != EOF && n) {
		printf("%llu\n", f[n][k]);
	}
	return 0;
}


UVA - 11077 Find the Permutations (置換)