2669: [cqoi2012]局部极小值

Time Limit: 3 Sec  Memory Limit: 128 MB
Submit: 774  Solved: 411
[Submit][Status][Discuss]

Description

有一个nm列的整数矩阵,其中1到nm之间的每个整数恰好出现一次。如果一个格子比所有相邻格子(相邻是指有公共边或公共顶点)都小,我们说这个格子是局部极小值。

给出所有局部极小值的位置,你的任务是判断有多少个可能的矩阵。

Input

输入第一行包含两个整数nm(1<=n<=4, 1<=m<=7),即行数和列数。以下n行每行m个字符,其中“X”表示局部极小值,“.”表示非局部极小值。

Output

输出仅一行,为可能的矩阵总数除以12345678的余数。

Sample Input

3 2
X.
..
.X

Sample Output

60

容斥,推一推可以得到X的个数不超过8个(虽然我不知道是怎么推的)
枚举,从小到大填数,状压dp可以计算出对于此种图的填数方案
用cnt[s]表示状态s下可以填数的方案(包括之前已经填过的X但不包括没填的X)
f[i][s]转移就得到啦(水一波)

这样我们可以保证X的位置一定是周围最小的,但却不能保证其他位置不会出现多余的'X'
于是我们dfs出每一个可以为X的地方,容斥一下就好啦
 
推荐blog
http://blog.csdn.net/popoqqq/article/details/48028773
 
取模有毒
a+=b;if(a>=mod)a-=mod;
如果b是负数的话..就炸了!!
调了1h..

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#define mod 12345678
#define ll long long
using namespace std;
int n,m,tp,cnt[<<],ok[][];
int dx[]={,,,-,,-,,-,};
int dy[]={,-,,,,-,-,,};
char mp[][];ll ans,f[][<<];
struct node{int x,y;}p[];
int dp(){
memset(cnt,,sizeof(cnt));
memset(f,,sizeof(f));tp=;
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
if(mp[i][j]=='X')
p[++tp]=(node){i,j};
for(int st=;st<(<<tp);st++){
memset(ok,,sizeof(ok));
for(int j=;j<=tp;j++)
if(!(st&(<<(j-))))ok[p[j].x][p[j].y]=;
for(int i=;i<=n;i++)
for(int k,j=;j<=m;j++){
for(k=;k<;k++)
if(ok[i+dx[k]][j+dy[k]])break;
if(k==)cnt[st]++;
}
}
f[][]=;
for(int i=;i<=n*m;i++)
for(int st=;st<(<<tp);st++){
(f[i][st]+=f[i-][st]*max(,cnt[st]-i+))%=mod;
for(int k=;k<=tp;k++)
if((<<(k-))&st)(f[i][st]+=f[i-][st^(<<(k-))])%=mod;
}
return f[n*m][(<<tp)-];
}
void dfs(int x,int y,int c){
int t;
if(x==n+){
(ans+=dp()*(c&?-:))%=mod;
return;
}
if(y==m)dfs(x+,,c);
else dfs(x,y+,c);
for(t=;t<;t++)if(mp[dx[t]+x][dy[t]+y]=='X')break;
if(t<)return;
mp[x][y]='X';
if(y==m)dfs(x+,,c+);
else dfs(x,y+,c+);
mp[x][y]='.';
}
int main(){
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)scanf("%s",mp[i]+);
for(int i=;i<=n;i++)
for(int j=;j<=m;j++)
if(mp[i][j]=='X')
for(int k=;k<;k++){
int nx=i+dx[k],ny=j+dy[k];
if(mp[nx][ny]=='X'){puts("");return ;}
}
dfs(,,);
ans<?ans+=mod:;
cout<<ans;
return ;
}

bzoj2669[cqoi2012]局部极小值 容斥+状压dp的更多相关文章

  1. P3160 [CQOI2012]局部极小值 题解(状压DP+容斥)

    题目链接 P3160 [CQOI2012]局部极小值 双倍经验,双倍快乐 解题思路 存下来每个坑(极小值点)的位置,以这个序号进行状态压缩. 显然,\(4*7\)的数据范围让极小值点在8个以内(以下示 ...

  2. [BZOJ2669][CQOI2012]局部最小值(容斥+状压DP)

    发现最多有8个限制位置,可以以此为基础DP和容斥. $f_{i,j}=f_{i-1,j}\times (cnt_j-i+1)+\sum_{k\subset j} f_{i-1,k}$ $cnt_j$表 ...

  3. ARC 093 F Dark Horse 容斥 状压dp 组合计数

    LINK:Dark Horse 首先考虑1所在位置. 假设1所在位置在1号点 对于此时剩下的其他点的方案来说. 把1移到另外一个点 对于刚才的所有方案来说 相对位置不变是另外的方案. 可以得到 1在任 ...

  4. bzoj3812 主旋律 容斥+状压 DP

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3812 题解 考虑对于图的联通性的 DP 的一般套路:总方案 - 不连通的方案. 那么我们只需要 ...

  5. Comet OJ - Contest #7 C 临时翻出来的题(容斥+状压)

    题意 https://www.cometoj.com/contest/52/problem/C?problem_id=2416 思路 这里提供一种容斥的写法(?好像网上没看到这种写法) 题目要求编号为 ...

  6. BZOJ2669 [cqoi2012]局部极小值 状压DP 容斥原理

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2669 题意概括 有一个n行m列的整数矩阵,其中1到nm之间的每个整数恰好出现一次.如果一个格子比所 ...

  7. 【bzoj2669】[cqoi2012]局部极小值 容斥原理+状压dp

    题目描述 有一个n行m列的整数矩阵,其中1到nm之间的每个整数恰好出现一次.如果一个格子比所有相邻格子(相邻是指有公共边或公共顶点)都小,我们说这个格子是局部极小值. 给出所有局部极小值的位置,你的任 ...

  8. 洛谷$P$3160 局部极小值 $[CQOI2012]$ 状压$dp$

    正解:状压$dp$ 解题报告: 传送门! 什么神仙题昂,,,反正我是没有想到$dp$的呢$kk$,,,还是太菜了$QAQ$ 首先看数据范围,一个4×7的方格,不难想到最多有8个局部极小值,过于显然懒得 ...

  9. HDU5731 Solid Dominoes Tilings 状压dp+状压容斥

    题意:给定n,m的矩阵,就是求稳定的骨牌完美覆盖,也就是相邻的两行或者两列都至少有一个骨牌 分析:第一步: 如果是单单求骨牌完美覆盖,请先去学基础的插头dp(其实也是基础的状压dp)骨牌覆盖 hiho ...

随机推荐

  1. 201421123042 《Java程序设计》第6周学习总结

    1. 本周学习总结 1.1 面向对象学习暂告一段落,请使用思维导图,以封装.继承.多态为核心概念画一张思维导图或相关笔记,对面向对象思想进行一个总结. 注1:关键词与内容不求多,但概念之间的联系要清晰 ...

  2. 不高兴的小名 nyoj

    不高兴的小明 时间限制:3000 ms  |  内存限制:65535 KB 难度:1   描述    小明又出问题了.妈妈认为聪明的小明应该更加用功学习而变的更加厉害,所以小明除了上学之外,还要参加妈 ...

  3. Win7下安装composer, 并使用其安装smarty

    安装composer需要开启PHP openssl扩展. 1) 先查看PHP是否开启了openssl扩展 键盘win+r 输出cmd, 可以看到Dos窗口, 然后执行php -m (需要添加PHP环境 ...

  4. TF中conv2d和kernel_initializer方法

    conv2d中的padding 在使用TF搭建CNN的过程中,卷积的操作如下 convolution = tf.nn.conv2d(X, filters, strides=[1,2,2,1], pad ...

  5. Python内置函数(44)——len

    英文文档: len(s) Return the length (the number of items) of an object. The argument may be a sequence (s ...

  6. Spring Security 入门(1-3-1)Spring Security - http元素 - 默认登录和登录定制

    登录表单配置 - http 元素下的 form-login 元素是用来定义表单登录信息的.当我们什么属性都不指定的时候 Spring Security 会为我们生成一个默认的登录页面. 如果不想使用默 ...

  7. DevExpress控件的GridControl实现行多选

    最近用到DevExpress控件的GridControl控件,需要用到行多选的操作,在网上找的资料,自己总结一下. 先展示一下效果:

  8. 南京邮电大学java程序设计作业在线编程第一次作业

    王利国的"Java语言程序设计第1次作业(2018)"详细 作业结果详细 总分:100 选择题得分:40  1. Java语言中,基本数据类型一共有( )种. A.16 B.2 C ...

  9. Linux环境下用C语言实现socket 通信---简单代码

    Socket编程实例: 服务器端:一直监听本机的8000号端口,如果收到连接请求,将接收请求并接收客户端发来的消息,并向客户端返回消息. 客户端:client.c /* File Name: clie ...

  10. POJ-2632 Crashing Robots模拟

    题目链接: https://vjudge.net/problem/POJ-2632 题目大意: 在一个a×b的仓库里有n个机器人,编号为1到n.现在给出每一个机器人的坐标和它所面朝的方向,以及m条指令 ...