CF293B Distinct Paths

题意

给定一个\(n\times m\)的矩形色板,有kk种不同的颜料,有些格子已经填上了某种颜色,现在需要将其他格子也填上颜色,使得从左上角到右下角的任意路径经过的格子都不会出现两种及以上相同的颜色。路径只能沿着相邻的格子,且只能向下或者向右。

计算所有可能的方案,结果对 \(1000000007 (10^9 + 7)\)

输入及输出格式

输入格式

第一行,三个整数$ n, m, k (1 \le n, m \le 1000, 1 \le k \le 10)$;

接下来\(n\)行,每行包含\(m\)个整数,表示颜色。其中\(0\)表示未涂色,非\(0\)表示颜色的编号, 颜色编号为\(1\)到\(k\)。

输出格式

一行,一个整数,表示涂色方案对$ 1000000007 (10^9 + 7)$求模的结果。

样例

此处就不挂了:传送门

思路

看似数据很大:\(n, m, k (1 \le n, m \le 1000, 1 \le k \le 10)\),但是,\(k<n+m-1\) 时,可以直接输出\(0\)。因为无法走完一条路径(一条路径长度为\(n+m-1\),因为是只能向下、向右走)。

那么实际数据范围很小,大概是$n+m-1 \le 10 $左右吧。

这么小的范围很容易就可想到\(dfs\)。这里有两个优化,一个是如果搜到一半,发现剩下的颜色不够用了就直接\(return\)。还有一个就是利用颜色\(A\)与颜色\(B\)的先后次序问题,路径\(AB\)与路径\(BA\)并不是同一种方案,所以搜索时如果搜到是第一次时,就可以直接乘\(now\)就可以省去很多\(dfs\)。

代码很丑,勿喷。

#include<algorithm>
#include<bitset>
#include<complex>
#include<deque>
#include<exception>
#include<fstream>
#include<functional>
#include<iomanip>
#include<ios>
#include<iosfwd>
#include<iostream>
#include<istream>
#include<iterator>
#include<limits>
#include<list>
#include<locale>
#include<map>
#include<memory>
#include<new>
#include<numeric>
#include<ostream>
#include<queue>
#include<set>
#include<sstream>
#include<stack>
#include<stdexcept>
#include<streambuf>
#include<string>
#include<typeinfo>
#include<utility>
#include<valarray>
#include<vector>
#include<cstring>
#include<cmath>
#define MOD 1000000007
using namespace std;//恶心的头文件
inline int read(){
char ch=getchar();int res=0,f=1;
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') res=res*10+ch-'0',ch=getchar();
return res*f;
}//读入优化
inline void write(int zx){
if(zx<0) zx=-zx,putchar('-');
if(zx<10) putchar(zx+'0');
else{
write(zx/10);
putchar(zx%10+'0');
}
}//输出优化
int n,m,k,cnt[50],a[50][50],sum,f[30][30],ps,ans,vv;
int dfs(int x,int y){
if(y==m+1){return dfs(x+1,1);}
if(x==n+1) return 1;
int S=0,num=0,mar=0,res=0,las=0;
f[x][y]=f[x-1][y]|f[x][y-1];
for(int i=1;i<=k;i++){
if(!(f[x][y]&(1<<i-1))) ++num;
}
if(num<n+m-x-y+1) return 0;//第一个优化
if(a[x][y]==0){
for(int i=1;i<=k;i++){
if(!(f[x][y]&(1<<i-1))){
if(cnt[i]==0){
if(mar) res+=las,res%=MOD;//第二个优化
else{
mar=1;
cnt[i]++;
f[x][y]|=1<<i-1;
las=dfs(x,y+1);
f[x][y]^=1<<i-1;
cnt[i]--;
res+=las;
res%=MOD;
}
continue ;
}
cnt[i]++;
f[x][y]|=1<<i-1;
res+=dfs(x,y+1);
f[x][y]^=1<<i-1;
cnt[i]--;
res%=MOD;
}
}
}else{
if(!(f[x][y]&(1<<a[x][y]-1))){
f[x][y]|=1<<a[x][y]-1;
res+=dfs(x,y+1);
f[x][y]^=1<<a[x][y]-1;
res%=MOD;
}
}
return res;
}
int main(){
n=read();m=read();k=read();
vv=n+m-1;
if(k<vv){//开始先特判
puts("0");
return 0;
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
a[i][j]=read();
cnt[a[i][j]]++;
}
}
ans=dfs(1,1);
cout<<ans<<endl;
return 0;
}

CF293B Distinct Paths题解的更多相关文章

  1. CF293B. Distinct Paths

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

  2. CF293B Distinct Paths 搜索

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

  3. [codeforces 293]B. Distinct Paths

    [codeforces 293]B. Distinct Paths 试题描述 You have a rectangular n × m-cell board. Some cells are alrea ...

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

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

  5. "Shortest" pair of paths[题解]

    "Shortest" pair of paths 题目大意 给出 \(n\) 个点,\(m\) 条边,除第一个点和最后一个点外,其他所有的点都只能被经过一次,要求找到两条从第一个点 ...

  6. World Tour Finals 2019 D - Distinct Boxes 题解

    太神了,专门写一篇题解 qwq 简要题意:给你 \(R\) 个红球和 \(B\) 个蓝球,你要把它们放到 \(K\) 个箱子里,要求没有两个箱子完全相同(即两种球个数就相同),求 \(K\) 的最大值 ...

  7. POJ3068:"Shortest" pair of paths——题解

    http://poj.org/problem?id=3068 题目大意: 从0-n-1找到两条边和点都不相同(除了0和n-1外)的最小费用路径. ——————————————————————————— ...

  8. POJ3177:Redundant Paths——题解

    http://poj.org/problem?id=3177 明显要求桥的一道题. (因为有桥就说明只能从那一条路走,换句话说就是只有一种方法) 求完桥后按照结论(加几条边成双连通图的结论,不会请ba ...

  9. SPOJ694/DISUBSTR:Distinct Substrings——题解

    https://vjudge.net/problem/SPOJ-DISUBSTR https://www.luogu.org/problemnew/show/SP694 http://www.spoj ...

随机推荐

  1. Ansible12:lookup

    目录 简单说明 1.file 2.pipe 3.env 4.template 5.csvfile 6.redis_kv 7.etcd 8.password 9.dnstxt 简单说明 在通常情况下,所 ...

  2. Mongodb 笔记01 MongoDB 简介、MongoDB基础知识、启动和停止MongoDB

    MongoDB 简介 1. 易于使用:没有固定的模式,根据需要添加和删除字段更加容易 2. 易于扩展:MongoDB的设计采用横向扩展.面向文档的数据模型使它能很容易的再多台服务器之间进行分割.自动处 ...

  3. TOMCAT添加管理用户认证

    添加配置文件 --原配置文件: # tail -5 /usr/local/tomcat/conf/tomcat-users.xml <user username="tomcat&quo ...

  4. css 系统自学笔记2017-12-04

    一.几个常用的可以连写的样式属性 1.backgroud: 背景连写:没有先后顺序,都是可选的. 2.font字体属性连写: font: 二.元素分类 块级元素:div p h1~h6 ul li o ...

  5. HDU1505 City Game 悬线法

    题意: 给出一个像这样的矩阵 R F F F F F F F F F F F R R R F F F     F F F F F F F F F F F F 求F组成的最大子矩阵(面积最大) 有多组数 ...

  6. 50、多线程创建的三种方式之实现Runnable接口

    实现Runnable接口创建线程 使用Runnable创建线程步骤: package com.sutaoyu.Thread; //1.自定义一个类实现java.lang包下的Runnable接口 cl ...

  7. Python文件操作-文件的增删改查

    需求:对文件进行增删改查 由于时间原因,本次代码没有增加任何注释,如有疑问,请联系编辑者:闫龙 其实我也是醉了,看着这些个代码,我脑袋也特么大了,没办法,大神说了,不让用新知识,只可以使用学过的,所以 ...

  8. php Only variables should be passed by reference 报错问题

    这个错误是变量引用引起的非致命错误,可修改php.ini文件的error_reporting = E_ALL & E_NOTICE 使其屏蔽此错误

  9. 使用转义防御XSS

    使用转义防御XSS 在输出的时候防御XSS即对用户输入进行转义,XSS的问题本质上还是代码注入,HTML或者javascript的代码注入,即混淆了用户输入的数据和代码.而解决这个问题,就需要根据用户 ...

  10. PE文件结构及其加载机制

    一.PE文件结构 PE即Portable Executable,是win32环境自身所带的执行体文件格式,其部分特性继承自Unix的COFF(Common Object File Format)文件格 ...