【2020.12.03提升组模拟】袋鼠

题目

题目描述

你知道吗?乌拉圭的人口有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\)

Code

#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;
}
相关文章
相关标签/搜索