[codeforces 293]B. Distinct Paths

试题描述

You have a rectangular n × m-cell board. Some cells are already painted some of k colors. You need to paint each uncolored cell one of the k colors so that any path from the upper left square to the lower right one doesn't contain any two cells of the same color. The path can go only along side-adjacent cells and can only go down or right.

Print the number of possible paintings modulo 1000000007 (109 + 7).

输入

The first line contains three integers n, m, k (1 ≤ n, m ≤ 1000, 1 ≤ k ≤ 10). The next n lines contain m integers each — the board. The first of them contains m uppermost cells of the board from the left to the right and the second one contains m cells from the second uppermost row and so on. If a number in a line equals 0, then the corresponding cell isn't painted. Otherwise, this number represents the initial color of the board cell — an integer from 1 to k.

Consider all colors numbered from 1 to k in some manner.

输出

Print the number of possible paintings modulo 1000000007 (109 + 7).

输入示例


输出示例


数据规模及约定

见“输入

题解

容易发现当 n + m - 1 > k 时,答案永远是 0,所以真正需要计算的数据范围是 n, m <= 10 且 n + m <= 11,那么这个地图就很小了,最多有 25 个块。

然后我想状压 dp,发现根本没法转移。。。上网搜了一下题解发现是大爆搜 + 剪枝。。。

贴个传送门,上面两种剪枝讲得很清楚。(戳这里

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <stack>
#include <vector>
#include <queue>
#include <cstring>
#include <string>
#include <map>
#include <set>
using namespace std; const int BufferSize = 1 << 16;
char buffer[BufferSize], *Head, *Tail;
inline char Getchar() {
if(Head == Tail) {
int l = fread(buffer, 1, BufferSize, stdin);
Tail = (Head = buffer) + l;
}
return *Head++;
}
int read() {
int x = 0, f = 1; char c = getchar();
while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
return x * f;
} #define maxn 15
#define maxs 1100
#define MOD 1000000007
int n, m, k, A[maxn][maxn]; int s[maxn][maxn], ans, col[maxn][maxn], use[maxn];
int dfs(int x, int y) {
// printf("%d %d\n", x, y);
// for(int i = 1; i <= n; i++) {
// for(int j = 1; j <= m; j++) printf("%d ", col[i][j]);
// putchar('\n');
// }
// putchar('\n');
if(x > n) return 1;
s[x][y] = s[x-1][y] | s[x][y-1];
int cnt = 0;
for(int i = 0; i < k; i++) if(s[x][y] >> i & 1) cnt++;
if(k - cnt < (n - x) + (m - y) + 1) return 0;
if(A[x][y] && (s[x][y] >> A[x][y] - 1 & 1)) return 0;
int ans = 0, sum = -1;
if(!A[x][y]) {
for(int i = 1; i <= k; i++) if(!(s[x][y] >> i - 1 & 1)) {
if(!use[i] && sum >= 0) {
ans += sum;
if(ans >= MOD) ans -= MOD;
continue;
}
s[x][y] ^= (1 << i - 1); use[i]++; col[x][y] = i;
int tmp = 0;
if(y < m) tmp = dfs(x, y + 1); else tmp = dfs(x + 1, 1);
s[x][y] ^= (1 << i - 1); use[i]--; col[x][y] = 0;
ans += tmp;
if(ans >= MOD) ans -= MOD;
if(!use[i]) sum = tmp;
}
}
else {
s[x][y] ^= (1 << A[x][y] - 1); use[A[x][y]]++; col[x][y] = A[x][y];
if(y < m) ans += dfs(x, y + 1); else ans += dfs(x + 1, 1);
s[x][y] ^= (1 << A[x][y] - 1); use[A[x][y]]--; col[x][y] = 0;
if(ans >= MOD) ans -= MOD;
}
return ans;
} int main() {
n = read(); m = read(); k = read();
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++) A[i][j] = read(), use[A[i][j]] = 1; printf("%d\n", dfs(1, 1)); return 0;
}

[codeforces 293]B. Distinct Paths的更多相关文章

  1. [codeforces 293]A. Weird Game

    [codeforces 293]A. Weird Game 试题描述 Yaroslav, Andrey and Roman can play cubes for hours and hours. Bu ...

  2. CF293B Distinct Paths题解

    CF293B Distinct Paths 题意 给定一个\(n\times m\)的矩形色板,有kk种不同的颜料,有些格子已经填上了某种颜色,现在需要将其他格子也填上颜色,使得从左上角到右下角的任意 ...

  3. CF293B. Distinct Paths

    B. Distinct Paths time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...

  4. Codeforces 293B Distinct Paths DFS+剪枝+状压

    目录 题面 题目链接 题意翻译 输入输出样例 输入样例#1 输出样例#1 输入样例#2 输出样例#2 输入样例#3 输出样例#3 输入样例#4 输出样例#4 说明 思路 AC代码 总结 题面 题目链接 ...

  5. CodeForces 1073F Choosing Two Paths

    Description You are given an undirected unweighted tree consisting of \(n\) vertices. An undirected ...

  6. 【CodeForces】870 F. Paths

    [题目]F. Paths [题意]给定数字n,图上有编号为1~n的点,两点当且仅当gcd(u,v)≠1时有连边,定义d(u,v)为两点间最短距离(若不连通则为0),求Σd(u,v),1<=u&l ...

  7. CF293B Distinct Paths 搜索

    传送门 首先数据范围很假 当\(N + M - 1 > K\)的时候就无解 所以对于所有要计算的情况,\(N + M \leq 11\) 超级小是吧,考虑搜索 对于每一个格子试填一个数 对于任意 ...

  8. Codeforces 981H:K Paths

    传送门 考虑枚举一条路径 \(u,v\),求出所有边经过它的答案 只需要求出 \(u\) 的子树内选出 \(k\) 个可以重复的点,使得它们到 \(u\) 的路径不相交 不难发现,就是从 \(u\) ...

  9. [CF293B]Distinct Paths_搜索_剪枝

    Distinct Paths 题目链接:http://codeforces.com/problemset/problem/293/B 数据范围:略. 题解: 带搜索的剪枝.... 想不到吧..... ...

随机推荐

  1. PDA设备小知识--(IP)工业防护等级含义

    IP(INTERNATIONAL PROTECTION)防护等级是专门的工业防护等级,,它将电器依其防尘.防湿气之特性加以分级.IP防护等级是由两个数字所组成,第1个数字表示电器离尘.防止外物侵入的等 ...

  2. ASP.NET服务器控件使用之MultiView和View

    MultiView 控件是一组 View 控件的容器.使用它可定义一组 View 控件,其中每个 View 控件都包含子控件. 用 ActiveViewIndex 属性或SetActiveView 方 ...

  3. C#中值类型和引用类型

    本文将介绍C#类型系统中的值类型和引用类型,以及两者之间的一些区别.同时,还会介绍一下装箱和拆箱操作. 值类型和引用类型 首先,我们看看在C#中哪些类型是值类型,哪些类型是引用类型. 值类型: 基础数 ...

  4. Xdebug开源PHP程序调试器

    Xdebug是一个开放源代码的PHP程序调试器(即一个Debug工具),可以用来跟踪,调试和分析PHP程序的运行状况. 本文为大家讲解的是在linux下xdebug的安装和配置方法,感兴趣的同学参考下 ...

  5. [转]SQL注入攻防入门详解

    原文地址:http://www.cnblogs.com/heyuquan/archive/2012/10/31/2748577.html =============安全性篇目录============ ...

  6. [Asp.net mvc] Asp.net mvc Kendo UI Grid的使用(四)

    有段时间没写博客了,工作状态比较忙,抽空继续总结下Grid的使用,这次主要介绍模板以及其他官网介绍不详尽的使用方法.先Show出数据,然后讲解下.后台代码: public ActionResult O ...

  7. 【HDU 2604】Queuing

    题 题意 f和m两种字母组成字符串,fmf 和 fff 这种为不安全的字符串,现在有2*L个字母,问你有多少安全的字符串.答案mod M. 分析 递推,这题本意是要用矩阵快速幂.不过我发现这题好神奇, ...

  8. 【CodeForces 624D】Array GCD

    题 You are given array ai of length n. You may consecutively apply two operations to this array: remo ...

  9. MyBatis架构设计及源代码分析系列(一):MyBatis架构

    如果不太熟悉MyBatis使用的请先参见MyBatis官方文档,这对理解其架构设计和源码分析有很大好处. 一.概述 MyBatis并不是一个完整的ORM框架,其官方首页是这么介绍自己 The MyBa ...

  10. Laravel 5 中的配置

    介绍 Laravel 的所有的配置文件都放在了 config 这个目录的下面.每个选项都有介绍. config├── app.php├── auth.php├── cache.php├── compi ...