【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;
}
相關文章
相關標籤/搜索