Topics
We need to count the number of ways to permute n
elements such that no element appears in its original position.
Using recurrence, we can get:
where (there’s one way to arrange nothing - an empty permutation) and (you can’t arrange one element so it’s not in its original spot).
Intuition Behind the Formula:
Let’s say we have n
items. Consider the first item. It can go into any of the (n-1)
other positions. Let’s say it goes into position i
. Now, there are two possibilities:
- The
i
-th item goes into the first position. Then, we have(n-2)
remaining items, and we need to derange them, which can be done inD(n-2)
ways
- The
i
-th item doesn’t go into the first position. Now, we can think of the first position as the “forbidden” position for thei
-th item. So, we have(n-1)
items, and we need to derange them, which can be done inD(n-1)
ways
Therefore, D(n) = (n-1) * [D(n-1) + D(n-2)]
.
long long derangement(int n) {
if (n == 0) return 1;
if (n == 1) return 0;
return (n - 1) * (derangement(n - 1) + derangement(n - 2));
}
Note that this recursive implementaion is very similar to the fibonacci series implementation. Additionally, we can convert a recursive solution to an iterative one. In this case, the iterative version would be:
const int MOD = 1e9+7;
int derangement(int n) {
if (n == 0) return 1;
if (n == 1) return 0;
long long a = 1, b = 0, c;
for (int i = 2; i <= n; i++) {
c = (i - 1) * (a + b) % MOD;
a = b;
b = c;
}
return c;
}
Note
There’s another derangement recurrence dervied from direct formula. That is easier to implement in competitive programming