YbtOJ 递推算法课堂过关 例1 错排问题【递推(简单DP)】

在这里插入图片描述

思路

首先设 f [ n ] f[n] f[n] 表示n个数的满足题意的方案数
首先,设一个 k k k 号位置,如果我们将 n n n 放在k号位置 ( k ≠ n ) (k≠n) (k=n),那么有 ( n − 1 ) (n-1) (n1) 种放法
其次,我们🤔考虑 k k k 的放置。

  • k k k 放在 n n n 的位置:
    这样放的话剩下的无序的元素就还剩 ( n − 2 ) (n-2) (n2) 个,
    相当于把那 ( n − 2 ) (n-2) (n2) 个元素错排,方案数是 f [ n − 2 ] f[n-2] f[n2].
  • k k k 不放在n的位置:
    这样的话无序的元素就有 ( n − 1 ) (n-1) (n1) 个,
    相当于把 ( n − 1 ) (n-1) (n1) 个元素错排,方案数是 f [ n − 1 ] f[n-1] f[n1].

所以在 ( n − 1 ) (n-1) (n1) 的情况下就有 f [ n − 1 ] + f [ n − 2 ] f[n-1]+f[n-2] f[n1]+f[n2] 种放法。
总方案数就是 ( n − 1 ) × ( f [ n − 1 ] + f [ n − 2 ] ) (n-1)\times{(f[n-1]+f[n-2])} (n1)×(f[n1]+f[n2]) .

代码

#include<iostream>
#include<cstdio>
using namespace std;
long long n,f[21];
int main()
{
	cin>>n;
	f[1]=0,f[2]=1;
	for(int i=3; i<=n; i++)
	   f[i]=(i-1)*(f[i-1]+f[i-2]);
	cout<<f[n];
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值