输入包含多组数据,每组数据包含一个正整数n(2≤n≤20)。
对应每一组数据,输出一个正整数,表示无人收到自己邮件的种数。
2<br/>3
1<br/>2
//递归思想,第n个收件人可以递归到n-1个收件人与n-2个收件人之和
#include<iostream>
using namespace std;
long int Failrec(int n)
{
if(n<2)
return 0;
if(n==2)
return 1;
if(n==3)
return 2;
return (n-1)*(Failrec(n-1)+Failrec(n-2));
}
int main()
{
int n;
while(cin>>n)
{
int count=0;
cout<<Failrec(n)<<endl;
}
return 0;
}
// 主要是练练语法,这种题目的思想总是很难想到。所谓的动态规划问题:假设a放进了B中:分两种情况,
//一种情况是b放在A中,有D(n-2)种方法,另一种情况是b没有放在A中,实际上就是把b,c,d...放进
//A,C,D...中也就是有D(n-1)放法,而把a放进C,D,E...中有同样的D(n-1) + D(n-2)种放法,所以有n封信
//就应该有(n-1)[D(n-1) + D(n-2)]种放法。
lst = [0, 0, 1]
for i in range(3,21):
lst.append((i-1)*(lst[i-1]+lst[i-2]))
while True:
try:
N = int(input())
print(lst[N])
except:
break
#include <stdio.h>
#define maxN 21
int main()
{
int i;
int N;
long long a[maxN] = {0, 0, 1, 2};
for(i=4;i<maxN;i++)
{
a[i] = (i-1)*(a[i-1] + a[i-2]);
}
while(scanf("%d", &N)!=EOF)
{
printf("%lld\n", a[N]);
}
}
#include<stdio.h>
int N=0;
void dfs(int,int);
int book[100]={0};
int main()
{
int n;
scanf("%d",&n);
dfs(0,n);
printf("%d",N);
}
void dfs(int step,int n)
{
if(step==n) N++;
else
{
int i;
for(i=0;i<n;i++)
if(book[i]==0&&i!=step) //没访问过并且自己的位置的编号不等于自己的值
{
book[i]=1;
dfs(step+1,n);
book[i]=0;
}
}
}//这是不需要什么数学公式推导的最暴力的方法
import java.util.Scanner;
//用的是单步最优的考虑想法,从最后一步开始考虑。
//为了方便理解,假设有5个人ABCDE,原来只有4个人ABCD。则多出来的一个人E,
//多出来的邮件E必定发错给ABCD中一个,共四种方法。假设给E的邮件发给了D,则
// 人 : A B C D E
// 邮件: E
//则发给D的邮件D有两种情况:一是正好发给了人E,二是发给了E以外的人(ABC)
//若情况一:变成了3人各自错收了邮件。
//若情况二:由于D不能发给E,我们可以假象D就是E(和原来等价),则此时变成了ABCE错发给ABCE,就等价于4人错收邮件。
//这样就很明白了,f(n)=(n-1)*[f(n-2)+f(n-1)]
public class Main {
public static void main(String[] args) {
Scanner in= new Scanner(System.in);
long c[]=new long[22];
c[2]=1;
c[3]=2;
for(int i=4;i<22;i++){
c[i]=(i-1)*(c[i-1]+c[i-2]);
}
while(in.hasNext()){
int n=in.nextInt();
System.out.println(c[n]);
}
}
}
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
int n = sc.nextInt();
long[] arr = new long[21];
arr[0] = 0;
arr[1] = 0;
arr[2] = 1;
for(int i = 3;i < arr.length;i++){
arr[i] = (i - 1) * (arr[i - 1] + arr[i - 2]);
}
System.out.println(arr[n]);
}
}
} #include <iostream>
#include <vector>
using namespace std;
int main()
{
int n;
while(cin >> n)
{
vector<long long> v(n + 1, 0);
v[1] = 0;
v[2] = 1;
for(int i = 3; i <= n; i++)
v[i] = (i - 1) * (v[i - 1] + v[i - 2]);
cout << v[n] << endl;
}
return 0;
} import java.util.*;
public class Main {
public static void main(String[] args){
Scanner scan = new Scanner(System.in);
long[] a = new long[22];
a[2] = 1;
a[3] = 2;
for (int i = 4; i < 22; i++){
a[i] = (i-1)*(a[i-1]+a[i-2]);
}
while (scan.hasNext()){
int n = scan.nextInt();
System.out.println(a[n]);
}
}
} //详细解说看博客
import java.util.Scanner;
public class Main2 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
int n = sc.nextInt();
long sum = count(n);
System.out.println(sum);
}
}
//计算所有人都收不到自己的邮件的情况情况:错排算法
private static long count(int n) {
if (n == 1) {
return 0;
} else if (n == 2) {
return 1;
} else {
return (n - 1) * (count(n - 1) + count(n - 2));
}
}
}
————————————————
版权声明:本文为CSDN博主「峰回路转」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_44840148/article/details/104723196 while True: try: n, num = int(input()), [1, 2] cout = 2 while len(num) < n: num.append((num[-1] + num[-2])*(cout+1)) cout += 1 print(num[-2]) except: break
#include <iostream>
using namespace std;
int main() { long long num[20] = {1, 2}; for (int i = 2; i < 20; i++) num[i] = (num[i-1] + num[i-2]) * (i + 1); int n; while (cin >> n) { cout << num[n-2] << endl; } return 0;
}
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
int main()
{ int n,i; long long a[25]={0,0,1}; for(i=3;i<=20;i++) { a[i] =(i-1)*(a[i-2]+a[i-1]); } while(cin>>n) { cout<<a[n]<<endl; } return 0; }
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
while (sc.hasNext()) {
int n = sc.nextInt();
System.out.println(count(n));
}
}
/**
* 错排算法,注意是long型
* @param n
* @return
*/
public static long count(int n) {
if (n == 1) {
return 0;
} else if (n == 2) {
return 1;
} else {
return (n - 1) * (count(n - 1) + count(n - 2));
}
}
}
有了递推公式,一切就迎刃而解了。
int main (void)
{
long long der[ 21 ] = { 0, 0, 1 };
int i;
for ( i = 3; i < 21; i++ ){
der[ i ] = ( i - 1 ) * ( der[ i - 2] + der[ i - 1 ] );
}
int n;
while ( scanf( "%d", &n ) != EOF ){
printf("%lld\n", der[ n ] );
}
return 0;
}