当前位置 博文首页 > ApocalypseTq的博客:P1497 木牛流马 题解
这里要运用到两个小学的知识点(摘自百度):
排列的定义: 从?nn?个不同元素中取出?m(m≤n)m(m≤n)?个元素的所有排列的个数,叫做从?nn?个不同元素中取出?mm?个元素的排列数,用符号?A(n,m)A(n,m)?表示。
计算公式:
A(m,n)=\prod_{n-m+1}^{n}=\frac{n!}{(n-m)!}A(m,n)=n?m+1∏n?=(n?m)!n!?
组合的定义:从?nn?个不同元素中取出?m(m≤n)m(m≤n)?个元素的所有组合的个数,叫做从?nn?个不同元素中取出?mm?个元素的组合数。用符号?C(n,m)C(n,m)?表示。
计算公式:
C(m,n)=\frac{A(m,n)}{m!}=\frac{n!}{m!(n-m)!}C(m,n)=m!A(m,n)?=m!(n?m)!n!?
有了这两个公式,做这题就轻松多了
回归正题,该如何考虑摆放的位置(假设都是一样的颜色)?
先看摆哪一些行:从?nn?行里选?kk?行,自然就是?C(k,n)C(k,n)?了
再看列该怎么摆:从?nn?列里选?kk?列,并与行对应(其实就是排列),共有?A(k,n)A(k,n)?种方法。
∴∴?摆放的位置共有?C(k,n)*A(k,n)C(k,n)?A(k,n)?个
考虑完位置,该看颜色了
每次从?kk?个木牛流马中选出?ii?个涂一种颜色,都有?C(i,k)C(i,k)?种涂法。但是要注意涂完颜色都要从?kk?里减去?ii,因为
这i个已经涂过颜色,不能再涂了
根据上文的推理,得到代码:
#include<stdio.h>//头文件
int n,k,h;
long long ans=1,temp;//用long long防止结果过大
int main(void){
register int i,j;
scanf("%d%d%d",&n,&k,&h);//读入
if(k>n)//如果k>n,答案为0
return puts("0"),0;
for(i=n-k+1;i<=n;i++)
ans*=i;//求n(n-1)(n-2)...(n-k+1)
ans*=ans;//算平方
for(i=1;i<=h;i++){
scanf("%lld",&temp);
for(j=2;j<=temp;j++)//因为除以1没有用,所以j从2开始
ans/=j;//进行除法
}
printf("%lld",ans);//输出
return 0;
}
cs