错排问题的递推公式

博客探讨了错排问题,即寻找所有数字不在对应序号位置的排列数量。通过分析,提出了递推公式:D(n) = (n-1) * (D(n-1) + D(n-2)),该公式用于计算n个数字的错排数目,并指出这一概念在某些编程竞赛题中有所应用。

问题描述

考虑一个n个数字的排列,使所有的数字都不在自己所对应序号的位置上,这样的一个排列就称为原排列的一个错排,现在给定一个数字n,求解所有可能的错排的个数。

分析

首先使用 D(n) D ( n ) 表示n个数字的错排数目, D(n1) D ( n − 1 ) 表示n-1个数字的全排列数目,以此类推,推导过程:

  1. 对于第 N N 个位置的数字n,首先选取一个位置 K K (任意的非N的位置)放置,共有 (n1) ( n − 1 ) 种情况
  2. 然后考虑第 K K 个位置的数字k,如果 k k 放在第N个位置,那么相当于剩下的 (n2) ( n − 2 ) 个数字进行错排,即共有 D(n2) D ( n − 2 ) 种情况,( n n k都已经确定了位置),如果 k k 不放在第n个位置,那么就相当于 (n1) ( n − 1 ) 个数字进行错排,也就是 D(n1) D ( n − 1 ) ,(这种情况,只有 n n 的位置确定了)

综上,所有的情况就是:
D(n)=(n1)(D(n1)+D(n2))

这就是n个数字进行错排的递推公式,很多题目,例如SDUT2058,都考察到了这一点:
代码:

#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<iostream>
using namespace std;

long long int sav[25];
int n;
int main(){
    sav[1]=0;
    sav[2]=1;
    for(int i=3; i<21; i++){
        sav[i] = (i-1) * (sav[i-1] + sav[i-2]);
    }
    while(cin>>n){
        cout<<sav[n]<<endl;
    }

    return 0;
}

以上~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值