飞行棋【DFS+剪枝】

>Link

luogu U137467


>Description

众所周知,飞行棋每个人会执不同颜色的飞行棋子,由于人数众多,牛牛的飞行棋盘和正常的有点不一样,是一个n*m大 小的棋盘,游戏开始时每个人可以在棋盘的任意位置放上自己的若干个棋子,也可以不放,当然每个位置只能放一 个,之后大家齐心协力填满这个棋盘,唯一的要求是在任意一条从左上角到右下角的路线上不能出现相同的棋子, 这里的路线只能向下和向右走,他们想知道总共有多少种方案数,很显然方案数可能有很多,所以只需要你告诉他们方案数对1000000007(10^9+7)取模的结果即可。

对于100%的数据,0<n,m,k<=10


>解题思路

正解就是爆搜+不断剪枝

我们从左到右从上到下填数
剪枝:

  1. 可以知道满足题目条件的话,当前格的数是不能在它的左上矩阵、右下矩阵里面其他地方出现的,所以我们可以维护一个左上矩阵、右下矩阵已填的数的二进制形式(右下矩阵还没搜到,这里表示原本已经填好的数)
  2. 路径长度可以求出来,如果剩下要走的长度大于了剩下没填的数的个数,说明不可行
  3. 如果有两个数要填在当前这个位,且它们在整个矩阵中都是第一次出现(之前搜索填好的和原本填好的),那它们搜索下去的方案数都是一样的,我们不用重复搜

>代码

#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 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值