杭电2048-杭电2049错排公式
这两题只要知道错排公式就可以AC了。
M(n)=(n-1)[M(n-2)+M(n-1)] 这个就是递推公式。
杭电2048只有有一个这个公式就可以了,2049还不够,还要有用组合数学。
杭电2048的代码:
#include<iostream> #include<cstdio> using namespace std; int main() { int n,case_num; cin>>case_num; while(case_num--) { cin>>n; __int64 *p=new __int64[n+1];//这种定义数组的方式,我感觉挺nb的。 这里一定要用__int64型,否则不够。 __int64 q=1; int i; p[1]=0; p[2]=1; for(i=3;i<=n;i++) { p[i]=(i-1)*(p[i-1]+p[i-2]); } for(i=1;i<=n;i++) { q*=i; } printf("%.2lf%%\n",(100.0)*p[n]/q);//这里输出可以学习一下 //这里漏了delete []p,竟然也可以过。 delete []p;//用了这个原本是236的,变成了232省了一点空间。 } }
杭电2049的代码:
代码
#include<iostream>
#include<cstdio>
using namespace std;
int i;
__int64 before(int n,int m)
{
long long bef1=1,bef2=1;
int p;
for(i=n,p=1;p<=(n-m);i--,p++)
{
bef1*=i;
}
for(i=n-m;i>=1;i--)
{
bef2*=i;
}
return bef1/bef2;
}
int main()
{
int n,m,a;
cin>>a;
while(a--)
{
cin>>n>>m;
__int64 *p =new __int64[m+1];//这样定义数组,就可以只开销m个单位空间
p[1] = 0;
p[2] = 1;
for(int i=3;i<m+1;i++)
{
p[i] = (i-1)*(p[i-1]+p[i-2]);//错排公式。
}
cout<<before(n,m)*p[m]<<endl;//刚开始的时候,错了,输出很大的数,后来才发现,p[m]写成了p[i]...无语ing。
delete []p;//销毁空间。
}
return 0;
}
继续努力ing。