[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. 【BZOJ1006】【HNOI2008】神奇的国度(弦图染色)

    1006: [HNOI2008]神奇的国度 Time Limit: 20 Sec  Memory Limit: 162 MBSubmit: 1467  Solved: 603[Submit][Stat ...

  2. [USACO2005][poj2229]Sumsets(递推)

    http://poj.org/problem?id=2229 分析: 显然的递推 若n为奇数,那么肯定是在n-1的基础上前面每个数+1,即f[n]=f[n-1] 若n为偶数 当第一位数字是1的时候,等 ...

  3. Go-MySQL-Driver:一个Go语言的轻量级极速的mysql驱动

    Go语言的 database/sql 包的一个 MySQL驱动. 特性 轻量级与快速 原生Go语言,没有C绑定,只有纯Go 没有不安全的操作(类型转换等) 动态处理崩溃的连接 动态连接池 支持大于16 ...

  4. chromiun 学习《二》 目录结构 +启动流程

    1.chromium的目录结构. 2.先上分析图一张.主要是从BrowserMain进程进行分析的.

  5. js简单的工厂模式

    <!DOCTYPE html> <html> <head> <title></title> </head> <body&g ...

  6. Java-httpClient警告: Going to buffer response body of large or unknown size. Using getResponseBodyAsStream instead is recommended.

    使用HttpClient,总是报出“Going to buffer response body of large or unknown size. Using getResponseBodyAsStr ...

  7. Java基础-JVM

    jvm=> java虚拟机 一.java虚拟机的生命周期: Java虚拟机的生命周期 一个运行中的Java虚拟机有着一个清晰的任务:执行Java程序.程序开始执行时他才运行,程序结束时他就停止. ...

  8. Oracle写函数读写日志实例

    1.用DBA登录赋权限create or replace directory D_OUTPUT as 'D:\TEMP'; grant read,write on directory D_OUTPUT ...

  9. UVA1262Password(第K字典序)

    题目链接 紫书P323 题意:两个6*5的字母矩阵,两个矩阵每列相同的字母,每列取一个,求按照字典序第k小的序列 分析: 对于第一个样例来说,我们得到{ACDW}.{BOP}.{GMOX}.{AP}. ...

  10. LocalDB简介和在VS2012及以上版本的使用

    http://www.cnblogs.com/fzrain/p/3812364.html?utm_source=tuicool LocalDB简介和在VS2012及以上版本的使用   之前一不小心把自 ...