SRM 176 Division-I, Level 2

Problem Statement
   
A derangement of n numbers is a permutation of those numbers in which none of the numbers appears in its original place. For example, the numbers {1,2,3} can be deranged into {2,3,1} and {3,1,2}. We can modify this slightly for n numbers that are not necessarily distinct by saying that no number in the derangement can be in the place that a number of the same value was in in the original ordering. So the numbers {1,1,2,2,3} could be deranged into {2,2,1,3,1}, {2,2,3,1,1}, {2,3,1,1,2}, and {3,2,1,1,2}. Create a class Deranged with a function numDerangements that takes a vector <int> nums and return the number of derangements of nums.
Definition
   
Class:
Deranged
Method:
numDerangements
Parameters:
vector <int>
Returns:
long long
Method signature:
long long numDerangements(vector <int> nums)
(be sure your method is public)
   

Notes
-
The return value will fit in a 64-bit unsigned integer.
Constraints
-
nums will contain between 1 and 15 elements, inclusive.
-
nums will only contain values between 0 and the number of elements in nums - 1, inclusive.
Examples
0)

   
{1,1,2,2,3}
Returns: 4
The example from above.
1)

   
{0,0,0,1,1,1}
Returns: 1
The only derangement is {1,1,1,0,0,0}.
2)

   
{0,0,0,1,1,1,1}
Returns: 0
There is no way to arrange the numbers such that no 1 is where a 1 was originally.
3)

   
{0,0,0,0,0,0,0,1,1,1,1,1,1,1,2}
Returns: 14

4)

   
{0,5,4,2,3,6,6}
Returns: 640

5)

   
{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14}
Returns: 481066515734

This problem statement is the exclusive and proprietary property of TopCoder, Inc. Any unauthorized use or reproduction of this information without the prior written consent of TopCoder, Inc. is strictly prohibited. (c)2003, TopCoder, Inc. All rights reserved.

This problem asked for the number of permutations of a set of numbers in which none of the elements remained in their original position. This problem is solvable in more than one way. One way is memoized recursion, which is the approach that most coders took. The solution I give here, however, uses the principle of inculsion-exclusion.

SRM 176 Division-I, Level 2

The principle of inclusion-exclusion gives a way of counting the number of unique items in a set of sets of items. I will give a general idea of how it works, for a more rigorous explanation, click here. Consider the Venn diagram to the right that shows three circles representing the primary colors of light and how they add together. The principle of inclusion-exclusion says that the total area covered by the three circles will be equal to the sum of the areas of each circle, minus the area of each intersection of two circles, plus the area of the intersection of all three circles. The general idea is to add the intersection of each group of an odd number of sets, and subtract the intersection of each group of an even number of sets.

Now to apply this to deranged permutations. First we need to be able to calculate the number of uniqe permutations of a set S. If S contains n elements, all of which are unique, then there exist n! permutations of S. If S contains n elements and the value v i occurs ki times in S, for i=1 through m, then the number of distinct permutations of S is given by n!/(k1!*k 2!*...*km-1!*km!). If we want to calculate the number of permutations of S when a subset of the elements in S are held in their original positions we can just remove those elements from S and then calculate the number of permutations of S with those elements removed. To calculate the number of permutations for which no element remains in its original position, we calculate the number of permutations of S in which at least one element remains in its original position, and subtract that number from the total number of permutations of S. To calculate the number of permutations for which at least one element remains in its original position we use the principle of inclusion-exclusion. The following pseudo-code demostrates how to do this, see writer's solution in the practice room for an implementation of this in C++.

long long numDerangements(S)
long long ret=numPermutations(S);
for i from 1 to the number of elements in S
for each combination, C, of i elements in S
if (i is odd) ret=ret-numPermutations(S-C);
if (i is even) ret=ret+numPermutations(S-C);
end
end
return ret;
end

你可能感兴趣的:(visio)