目录
不容易系列之(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;
}