错排公式及例题(HDU 1465、HDU 2049、HDU 2048、HDU 2047、HDU 2045)

目录

概念:

公式:

不容易系列之一 (HDU 1465)

不容易系列之(4)——考新郎 (HDU 2049)

神、上帝以及老天爷  (HDU 2048)

阿牛的EOF牛肉串  (HDU 2047)

不容易系列之(3)—— LELE的RPG难题(HDU 2045)


概念:

将一排的 N 个元素重新排列,使他们所有元素都不在自己原来位置上的方案数有多少。

百度百科的传送门:

https://baike.baidu.com/item/%E9%94%99%E6%8E%92%E5%85%AC%E5%BC%8F/10978508?fr=aladdin

 

在杭电讨论区看到的 觉得还不错 就i截下来放一下

 

公式:

(初始化 D(1)=0  D(2)=1  D(3)=2)

(化简后的式子,上面的网址中有证明) 

 

放几道例题:

不容易系列之一 (HDU 1465)

 

分析:

最基础的错排公式的运用

#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <queue>
long long a[25];
using namespace std;
int main()
{
    int n;
    a[1]=1;
    a[2]=1;
    a[3]=2;
    for (int i=4;i<24;i++)
    {
        a[i]=(i-1)*(a[i-1]+a[i-2]);
    }
    while (~scanf("%d",&n))
        printf("%lld\n",a[n]);
    return 0;
}

 

不容易系列之(4)——考新郎 (HDU 2049)

 

分析:

这题里面加入了 组合数学

所以还要考虑 从N中选M有多少种情况

#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <queue>
__int64 a[25];
using namespace std;
long long C(int n,int m)
{
    long long sum1=1,sum2=1;
    for (int i=1; i<=n; i++)
        sum1=sum1*i;
    for (int i=1; i<=m; i++)
        sum2=sum2*i;
    for (int i=1; i<=(n-m); i++)
        sum2=sum2*i;
    return sum1/sum2;
}
int main()
{
    int t,x,y;
    a[0]=0;
    a[1]=0;
    a[2]=1;
    a[3]=2;
    for (int i=4; i<24; i++)
    {
        a[i]=(i-1)*(a[i-1]+a[i-2]);
    }
    while (~scanf("%d",&t))
    {
        for (int i=0; i<t; i++)
        {
            scanf("%d%d",&x,&y);
            printf("%I64d\n",C(x,y)*a[y]);
        }
    }
    return 0;
}

 

神、上帝以及老天爷  (HDU 2048)

 

分析:

很容易就知道 可能发生的情况总数为  n!

所以 发生这种情况的百分率为 D(n) / n !

#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <queue>
long long a[25];
using namespace std;
int main()
{
    int t,n;
    a[1]=1;
    a[2]=1;
    a[3]=2;
    for (int i=4; i<24; i++)
    {
        a[i]=(i-1)*(a[i-1]+a[i-2]);
    }
    scanf("%d",&t);
    for (int j=0; j<t; j++)
    {
        scanf("%d",&n);
        long long sum = 1;
        for (int i=1; i<=n; i++)
            sum=sum*i;
        printf("%.2lf%%\n",a[n]*100.0/sum);
    }
    return 0;
}

 

阿牛的EOF牛肉串  (HDU 2047)

 

分析:

放入第n个牛肉干时 

1)当 n 为 E 或 F 时 : 2 × f ( n - 1 )

2)当 n 为 O 时 第 n - 1 个只能为E或者F :  2 × f ( n - 2 )

#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <queue>
long long a[45];
using namespace std;
int main()
{
    int n;
    a[1]=3;
    a[2]=8;
    for (int i=3; i<45; i++)
    {
        a[i]=2*(a[i-1]+a[i-2]);
    }
    while (~scanf("%d",&n))
    {
        printf("%lld\n",a[n]);
    }
    return 0;
}

 

不容易系列之(3)—— LELE的RPG难题(HDU 2045)

 

分析:

 如果有n个方格,当对第n个方格填色时,有两种情况:      

1)应该已经对前面n-1个方格填好了色,有f(n-1)种情况,此时第n-1个跟第一个颜色一定不一样,所以第n个只有一种选择。  2)对前面n-2个方格填好色,有f(n-2)种情况,第n-1个空格颜色跟第一个颜色一样(否则就成了上面那种情况了),只有一种可能,最后第n个方格可以填两种颜色(因为n-1和1是第同种颜色),所以是2*f(n-2);

可以推出f(n)=f(n-1)+2(n-2),n>=4;

#include <stdio.h>
#include <iostream>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <queue>
long long a[55];
using namespace std;
int main()
{
    int n;
    a[1]=3;
    a[2]=6;
    a[3]=6;
    for (int i=4;i<=55;i++)
        a[i]=a[i-1]+2*a[i-2];
    while (~scanf("%d",&n))
        printf("%lld\n",a[n]);
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值