2017百度之星初赛(B) 1001 Chess(找规律+递推求组合数)

题目链接:点击打开链接

思路:看到这个题呢,开始想的复杂了,可能受八皇后思维的影响,光想着怎么改进八皇后的算法,利用搜索去解题,此题的棋盘规模大,利用搜索和八皇后的思维肯定超时,而且一开始对题意有疑问,“摆最多个数的車“,何为最多个数?最后想不起来怎么修改算法,就去考虑,会不会是递推题或者分治题或者规律题?仔细一想,还真有规律可求,最多个数,就是这个棋盘最多放多少車,求在棋盘放这个数量的方案数,对于n * m的棋盘,显然最多个数就是min(n,m),車个数确定了,那怎么摆放呢?规则说明,最后摆放的車,大致呈自上而下、自左向右的样子,假设所有棋盘都按照n * m(n < m)处理,也就是放n个車,那么每一行都会放,对于列呢?也一定放在了不同的列,直接选取n个不同的列自上而下、自左向右摆放即可,总方案数C(m,n)。

所以此题归根结底就是通过预处理打表,递推出组合数。

// Chess.cpp 运行/限制:15ms/1000ms
#include 
#include 
#include 
#include 
using namespace std;
#define MOD 1000000007
long long c[1005][1005];
void init() {//预处理打表,递推组合数
	long long i, j;
	memset(c, 0, sizeof(c));
	for (i = 0; i <= 1000; i++)
		c[i][0] = 1;
	for (i = 1; i <= 1000; i++){
		for (j = 1; j <= i; j++){
			c[i][j] = (c[i - 1][j] + c[i - 1][j - 1]) % MOD;
		}
	}
}
int main(){
	int t, n, m;
	init();
	scanf("%d", &t);
	while (t--) {
		scanf("%d%d", &n, &m);
		int a = min(n, m);
		int b = max(n, m);
		printf("%I64d\n", c[b][a]);
	}
    return 0;
}


你可能感兴趣的:(百度之星)