>Link
luogu U137467
>Description
众所周知,飞行棋每个人会执不同颜色的飞行棋子,由于人数众多,牛牛的飞行棋盘和正常的有点不一样,是一个n*m大 小的棋盘,游戏开始时每个人可以在棋盘的任意位置放上自己的若干个棋子,也可以不放,当然每个位置只能放一 个,之后大家齐心协力填满这个棋盘,唯一的要求是在任意一条从左上角到右下角的路线上不能出现相同的棋子, 这里的路线只能向下和向右走,他们想知道总共有多少种方案数,很显然方案数可能有很多,所以只需要你告诉他们方案数对1000000007(10^9+7)取模的结果即可。
对于100%的数据,0<n,m,k<=10
>解题思路
正解就是爆搜+不断剪枝
我们从左到右从上到下填数
剪枝:
- 可以知道满足题目条件的话,当前格的数是不能在它的左上矩阵、右下矩阵里面其他地方出现的,所以我们可以维护一个左上矩阵、右下矩阵已填的数的二进制形式(右下矩阵还没搜到,这里表示原本已经填好的数)
- 路径长度可以求出来,如果剩下要走的长度大于了剩下没填的数的个数,说明不可行
- 如果有两个数要填在当前这个位,且它们在整个矩阵中都是第一次出现(之前搜索填好的和原本填好的),那它们搜索下去的方案数都是一样的,我们不用重复搜
>代码
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 20
#define LL long long
using namespace std;
const LL Mod = 1e9 + 7;
int n, m, k, a[N][N], f[N][N], ff[N][N];
LL ans;
bool use[N], orig[N];
void dfs (int x, int y)
{
if (x == n && y == m + 1)
{
ans = (ans + 1) % Mod;
return;
}
if (y == m + 1) x++, y