[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. 怎样提高Windows Azure Cloud Service中的WebRole的文件访问权限

    关键字:WebRole 1. 背景 Web应用程序需要读取和写入该项目下的文件的权限. 在默认情况下,W3wp.exe 和WaIISHost.exe的运行账号是Network Service,而Net ...

  2. 百度地图整合功能分享修正版[ZMap.js] 实例源码!

    ZMap 功能说明 ZMap 是学习百度地图 api 接口,开发基本功能后整的一个脚本类,本类方法功能大多使用 prototype 原型 实现: 包含的功能有:轨迹回放,圈画区域可编辑,判断几个坐标是 ...

  3. msf命令全集

    一.msfconsole ?   帮助菜单 back 从当前环境返回 banner   显示一个MSF banner cd   切换目录 color   颜色转换 connect   连接一个主机 e ...

  4. iOS边练边学--Http网络再学习,简单介绍

    一.URL 什么是URL URL中常见的协议 二.Http Http的基本通信过程 发送Http请求的方法 GET 和 POST 对比 GET 和 POST 的选择 三.iOS中的Http学习 iOS ...

  5. UVA5870 乱搞 Smooth Visualization

    #include<stdio.h> #include<string.h> #define maxn 1201 ][],s[maxn]; int col; int getmax( ...

  6. TCP/IP详解 笔记一

    概述: Tcp-ip让网络上的计算机进行通信,而不管计算机和操作系统是否一样. 分层结构: Tcp/ip协议族是多层协议的组合,而tcp和ip只是其中的两个协议而已. 一个通信举例: 注意图的右上方: ...

  7. 51NOD 1400 序列分解

    传送门:1400 序列分解序列分解 基准时间限制:1s  空间限制:131072 KBKB131072 KB 1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题1 秒 空间限制:13 ...

  8. Mac OS X 10.9 Mavericks安装后,Xcode调试时模拟器黑屏的处理方法

    请耐心的等下去吧,少年! 装了Mac OS X 10.9 Mavericks的同学,如果碰到Xcode调试App时,模拟器黑屏(重置也无效),请耐心的等下去吧,大约10来分钟左右黑屏就会消失,App启 ...

  9. omnetpp inet

    http://blog.csdn.net/midie/article/details/5086983 omnetpp inet 自带了Mingw编译环境,而不再需要Visual C编译环境了.事实上, ...

  10. 写给iOS程序员的命令行使用秘籍

    http://www.jianshu.com/p/44d3b8f713f2 Mac OS是Unix系统的分支,有着强大的命令行功能.很多事情在命令行下处理会事半功倍,所以我就iOS程序员可能会用到的功 ...