你知道吗?乌拉圭的人口有345.7万,同时,仅澳大利亚就有4700万只袋鼠。大数据
袋鼠决定入侵乌拉圭。袋鼠们将在平原上布阵,平原被划分红\(n\times m\)的网格。spa
每一个格子里至多有一只袋鼠。code
为了抵御袋鼠的入侵,你须要预测敌人的阵型。具体地,你须要计算袋鼠阵io
型的数目,知足平原网格中每行、每列的袋鼠数目之和均为\(K\).class
若是袋鼠入侵了乌拉圭,那么每个乌拉圭人都要打 14 只袋鼠。你不知道,im
你不在意,你只会在这里写这道无聊的题,你只关心你本身。数据
\(1\leq n,m\leq9\),\(0\leq k\leq min(n,m)\)di
题目大意:在\(n\times m\)的矩阵了填01,问有多少种方案使得每行每列都为\(k\)入侵
注意到\(n,m\)特别小,能够采起暴力打表。而容易推出在\(k=0\)时答案是1,而若是\(n\ne m\)且\(k\ne0\)时无解co
那么题目就能够转化成\(n\times n\)的矩阵,而容易发现\(k\)与\(n-k\)是具备对称性的,那么这个题的最大数据就是\(n=m=9,k=4\),这个用一个比较优秀的暴力(如记忆化)先跑出来,而后就打表
可贵的打表题呀,正解是状压\(dp\)
#include<cstdio> #define ll long long using namespace std; int n,m,k; ll a[15][15]={{1},{1},{1,2},{1,6},{1,24,90},{1,120,2040}, {1,720,67950,297200}, {1,5040,3110940,68938800}, {1,40320,187530840,24046189440,116963796250}, {1,362880,14398171200,12025780892160,315031400802720}};; int main() { freopen("algebra.in","r",stdin); freopen("algebra.out","w",stdout); scanf("%d%d%d",&n,&m,&k); if (n!=m) { if (k==0) printf("1\n"); else printf("0\n"); fclose(stdin); fclose(stdout); return 0; } if (2*k>n) k=n-k; printf("%lld\n",a[n][k]); fclose(stdin); fclose(stdout); return 0; }