bzoj2669[cqoi2012]局部极小值 容斥+状压dp
2669: [cqoi2012]局部极小值
Time Limit: 3 Sec Memory Limit: 128 MB
Submit: 774 Solved: 411
[Submit][Status][Discuss]
Description
有一个n行m列的整数矩阵,其中1到nm之间的每个整数恰好出现一次。如果一个格子比所有相邻格子(相邻是指有公共边或公共顶点)都小,我们说这个格子是局部极小值。
给出所有局部极小值的位置,你的任务是判断有多少个可能的矩阵。
Input
输入第一行包含两个整数n和m(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的更多相关文章
- P3160 [CQOI2012]局部极小值 题解(状压DP+容斥)
题目链接 P3160 [CQOI2012]局部极小值 双倍经验,双倍快乐 解题思路 存下来每个坑(极小值点)的位置,以这个序号进行状态压缩. 显然,\(4*7\)的数据范围让极小值点在8个以内(以下示 ...
- [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$表 ...
- ARC 093 F Dark Horse 容斥 状压dp 组合计数
LINK:Dark Horse 首先考虑1所在位置. 假设1所在位置在1号点 对于此时剩下的其他点的方案来说. 把1移到另外一个点 对于刚才的所有方案来说 相对位置不变是另外的方案. 可以得到 1在任 ...
- bzoj3812 主旋律 容斥+状压 DP
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=3812 题解 考虑对于图的联通性的 DP 的一般套路:总方案 - 不连通的方案. 那么我们只需要 ...
- Comet OJ - Contest #7 C 临时翻出来的题(容斥+状压)
题意 https://www.cometoj.com/contest/52/problem/C?problem_id=2416 思路 这里提供一种容斥的写法(?好像网上没看到这种写法) 题目要求编号为 ...
- BZOJ2669 [cqoi2012]局部极小值 状压DP 容斥原理
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2669 题意概括 有一个n行m列的整数矩阵,其中1到nm之间的每个整数恰好出现一次.如果一个格子比所 ...
- 【bzoj2669】[cqoi2012]局部极小值 容斥原理+状压dp
题目描述 有一个n行m列的整数矩阵,其中1到nm之间的每个整数恰好出现一次.如果一个格子比所有相邻格子(相邻是指有公共边或公共顶点)都小,我们说这个格子是局部极小值. 给出所有局部极小值的位置,你的任 ...
- 洛谷$P$3160 局部极小值 $[CQOI2012]$ 状压$dp$
正解:状压$dp$ 解题报告: 传送门! 什么神仙题昂,,,反正我是没有想到$dp$的呢$kk$,,,还是太菜了$QAQ$ 首先看数据范围,一个4×7的方格,不难想到最多有8个局部极小值,过于显然懒得 ...
- HDU5731 Solid Dominoes Tilings 状压dp+状压容斥
题意:给定n,m的矩阵,就是求稳定的骨牌完美覆盖,也就是相邻的两行或者两列都至少有一个骨牌 分析:第一步: 如果是单单求骨牌完美覆盖,请先去学基础的插头dp(其实也是基础的状压dp)骨牌覆盖 hiho ...
随机推荐
- 【iOS】swift-Binary operator '|' cannot be applied to two UIViewAutoresizing operands
let view = UIView(frame: CGRect(x: 0, y: 0, width: 320, height: 568)) addSubview(view) view.autoresi ...
- bzoj 2962 序列操作
2962: 序列操作 Time Limit: 50 Sec Memory Limit: 256 MB[Submit][Status][Discuss] Description 有一个长度为n的序列, ...
- (function(root,factory){})(this,function($){}) 一个立即执行的匿名函数自调
因为新公司用到ocx 我就开始看原来的代码 无意中发现这个 可能原来比较low吗(虽然现在也很low吧)没发现这个东东 还可以这样写 于是乎我开始了探索 完整代码如下 HTML <div id= ...
- Angular组件——组件生命周期(二)
一.view钩子 view钩子有2个,ngAfterViewInit和ngAfterViewChecked钩子. 1.实现ngAfterViewInit和ngAfterViewChecked钩子时注意 ...
- Jmeter入门(01)Jmeter的下载和安装
一.什么是Jmeter 1.一款优秀的.开源的.免费的.功能测试和性能测试 工具 Jmeter ,使用Java开发的一款优秀的开源免费测试工具,主要用来做功能测试和性能测试(压力测试/负载测试),用J ...
- Linux进程管理:查杀进程
一.查看进程 Linux下显示系统进程的命令ps,最常用的有ps -ef 和ps aux.这两个到底有什么区别呢? 两者没太大差别,讨论这个问题,要追溯到Unix系统中的两种风格,System V风格 ...
- Python入门之函数的形式参数与实参/参数的具体使用方法
本篇目录: 一. 函数参数之形式参数与实参 二. 函数参数的具体使用 #1.位置参数:按照从左到右的顺序定义的参数 位置形参:必选参数 位置实参:按照位置给形参传值 #2.关键字参数:按照key=va ...
- Spring Data Jpa简单了解
原文来源:http://www.cnblogs.com/xuyuanjia/p/5707681.html 以下是自己简单整理原有文章,其实就是在原来文章基础上化重点以及可能会有所删减的方式进行整理,需 ...
- 前端 jQuery
一.jQuery是什么? <1>jQuery由美国人John Resig创建,至今已吸引了来自世界各地众多JavaScript高手加入其team. <2>jQuery是继pro ...
- Java学习图形界面+网络编程案例---------网络简易通讯
主要思想: 主类继承JPanel,在构造方法中将JFrame设成空布局:在其中适当位置添加组件:实现事件监听处理 DATE:2015-10-31 服务器端代码: /** * @author Oyc * ...