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 ...
随机推荐
- Flask 学习 四 数据库
class Role(db.Model): __tablename__='roles' id = db.Column(db.Integer,primary_key=True) name = db.Co ...
- Hibernate之HQL
SQL语句的DML操作不外乎:增,删,改,查 增加 : save(),persist() 删除 : delete() 改动 : update() 查询 : get() ,load() 其 ...
- 20170222==(MODBUS读取多个寄存器)
MODBUS读取多个寄存器(功能码04) 为了简单我这里只用4个寄存器,当让你也可以用125个寄存器,但是最多也只能用125个寄存器的.每个寄存器有上面的表知道为一个字的大小即2个字节或者叫16比特位 ...
- C# 使用 GDI+ 实现添加中心旋转(任意角度)的文字
这篇文章是 GDI+ 总结系列的第三篇,如果对 GDI+ 的基础使用不熟悉的朋友可以先看第一篇文章<C# 使用 GDI+ 画图>. 需求 需求是要实现给图片添加任意角度旋转的文字,文字的旋 ...
- kubernetes入门(01)kubernetes是什么?
一.kubernetes是什么? Kubernetes是Google开源的一个容器编排引擎,它支持自动化部署.大规模可伸缩.应用容器化管理.在生产环境中部署一个应用程序时,通常要部署该应用的多个实例以 ...
- Jmeter入门(01)Jmeter的下载和安装
一.什么是Jmeter 1.一款优秀的.开源的.免费的.功能测试和性能测试 工具 Jmeter ,使用Java开发的一款优秀的开源免费测试工具,主要用来做功能测试和性能测试(压力测试/负载测试),用J ...
- 记java应用linux服务单个CPU使用率100%分析
之前在做项目的过程中,项目完成后在linux服务器上做性能测试,当服务跑起来的时候发现cpu使用率很奇怪,java应用把单个cpu跑满了,其他cpu利用率0%. 刚开始遇到这问题的时候我第一时间反应使 ...
- POJ1015 && UVA - 323 ~Jury Compromise(dp路径)
In Frobnia, a far-away country, the verdicts in court trials are determined by a jury consisting of ...
- 云+社区技术沙龙:Kafka meetup 深圳站报名开启
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 如果说 2018 年是技术大爆炸年,那么 Apache Kafka 绝对是其中闪亮的新星. 自Kafka 从首发之日起,已经走过了快八个年头 ...
- MyBatis(二):Select语句传递参数的集中方案
从别人说的方案中看出,传递参数方案还挺多,不如自己整理下,以便以后使用过程中有个笔记回忆录. 1.传递一个参数的用法: 配置文件 <select id="getById" r ...