[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).

输入示例

  1.  

输出示例

  1.  

数据规模及约定

见“输入

题解

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

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

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

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <algorithm>
  4. #include <cmath>
  5. #include <stack>
  6. #include <vector>
  7. #include <queue>
  8. #include <cstring>
  9. #include <string>
  10. #include <map>
  11. #include <set>
  12. using namespace std;
  13.  
  14. const int BufferSize = 1 << 16;
  15. char buffer[BufferSize], *Head, *Tail;
  16. inline char Getchar() {
  17. if(Head == Tail) {
  18. int l = fread(buffer, 1, BufferSize, stdin);
  19. Tail = (Head = buffer) + l;
  20. }
  21. return *Head++;
  22. }
  23. int read() {
  24. int x = 0, f = 1; char c = getchar();
  25. while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
  26. while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
  27. return x * f;
  28. }
  29.  
  30. #define maxn 15
  31. #define maxs 1100
  32. #define MOD 1000000007
  33. int n, m, k, A[maxn][maxn];
  34.  
  35. int s[maxn][maxn], ans, col[maxn][maxn], use[maxn];
  36. int dfs(int x, int y) {
  37. // printf("%d %d\n", x, y);
  38. // for(int i = 1; i <= n; i++) {
  39. // for(int j = 1; j <= m; j++) printf("%d ", col[i][j]);
  40. // putchar('\n');
  41. // }
  42. // putchar('\n');
  43. if(x > n) return 1;
  44. s[x][y] = s[x-1][y] | s[x][y-1];
  45. int cnt = 0;
  46. for(int i = 0; i < k; i++) if(s[x][y] >> i & 1) cnt++;
  47. if(k - cnt < (n - x) + (m - y) + 1) return 0;
  48. if(A[x][y] && (s[x][y] >> A[x][y] - 1 & 1)) return 0;
  49. int ans = 0, sum = -1;
  50. if(!A[x][y]) {
  51. for(int i = 1; i <= k; i++) if(!(s[x][y] >> i - 1 & 1)) {
  52. if(!use[i] && sum >= 0) {
  53. ans += sum;
  54. if(ans >= MOD) ans -= MOD;
  55. continue;
  56. }
  57. s[x][y] ^= (1 << i - 1); use[i]++; col[x][y] = i;
  58. int tmp = 0;
  59. if(y < m) tmp = dfs(x, y + 1); else tmp = dfs(x + 1, 1);
  60. s[x][y] ^= (1 << i - 1); use[i]--; col[x][y] = 0;
  61. ans += tmp;
  62. if(ans >= MOD) ans -= MOD;
  63. if(!use[i]) sum = tmp;
  64. }
  65. }
  66. else {
  67. s[x][y] ^= (1 << A[x][y] - 1); use[A[x][y]]++; col[x][y] = A[x][y];
  68. if(y < m) ans += dfs(x, y + 1); else ans += dfs(x + 1, 1);
  69. s[x][y] ^= (1 << A[x][y] - 1); use[A[x][y]]--; col[x][y] = 0;
  70. if(ans >= MOD) ans -= MOD;
  71. }
  72. return ans;
  73. }
  74.  
  75. int main() {
  76. n = read(); m = read(); k = read();
  77. for(int i = 1; i <= n; i++)
  78. for(int j = 1; j <= m; j++) A[i][j] = read(), use[A[i][j]] = 1;
  79.  
  80. printf("%d\n", dfs(1, 1));
  81.  
  82. return 0;
  83. }

[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. 数据结构之链表、栈和队列 java代码实现

    定义抽象节点类Node: package cn.wzbrilliant.datastructure; /** * 节点 * @author ice * */ public abstract class ...

  2. Bootstrap系列 -- 26. 下拉菜单标题

    Bootstrap下拉菜单中使用 dropdown-header 来显示菜单标题,和上一篇说道的分割线一样 <div class="dropdown"> <but ...

  3. The first gui program by Qt

    #include<QApplication> #include<QPushButton> int main(int argc, char **argv) {     QAppl ...

  4. poj3468 splay(成段跟新 区间求和)

    用splay做了一遍. 建树时是按照数列序号从小到大排好的,每个节点左子树的序号小于右子树的序号及这个节点本身.由于查询[l,r]要伸展l-1,r+1所以我们要多加2个结点,保证边界处理时不出问题.由 ...

  5. 图解Android - Looper, Handler 和 MessageQueue

    Looper, Handler 和 MessageQueue 是Android 的异步消息处理机制

  6. iframe标签用法详解(属性、透明、自适应高度)

    1.iframe 定义和用法 iframe 元素会创建包含另外一个文档的内联框架(即行内框架). HTML 与 XHTML 之间的差异 在 HTML 4.1 Strict DTD 和 XHTML 1. ...

  7. 【POJ 3020】Antenna Placement(二分图匹配)

    相当于用1*2的板覆盖给定的h*w的格子里的点,求最少的板.可以把格子相邻的分成两个集合,如下图,0为一个集合,1的为一个,也就是(行数+列数)为奇数的是一个集合,为偶数的为另一个集合.1010101 ...

  8. 【蒟蒻の进阶PLAN】 置顶+持续连载

    看到周围神犇们纷纷列计划,本蒟蒻也决定跟随他们的步伐,计划大约是周计划吧,具体怎么安排我也不确定.. 2015.12.30 刚刚学习完最基础的网络流,需要进行这方面的练习,从简到难,有空余的话尝试学习 ...

  9. 15个Linux Wget下载实例终极指南

    15个Linux Wget下载实例终极指南 Linux wget是一个下载文件的工具,它用在命令行下.对于Linux用户是必不可少的工具,尤其对于网络管理员,经常要下载一些软件或从远程服务器恢复备份到 ...

  10. ucenter实现原理

    其实Ucenter实现同步登陆的原理就是cookie,一个应用登陆成功之后,向Ucenter传递数据(post方式),让Ucenter通知其他的应用也设置 cookie(get方式),这样用户在访问其 ...