[BZOJ2669][CQOI2012]局部极小值:DP+容斥原理
分析
题目要求有且只有一些位置是局部极小值。有的限制很好处理,但是只有嘛,嗯......
考虑子集反演(话说这个其实已经算是超集反演了吧还叫子集反演是不是有点不太合适),枚举题目给出位置集合的所有超集,计算让这些位置成为局部极小值,而其他位置随意的方案数,这个可以通过DP,从小到大插入每个数解决。
搜索加一些剪枝,然后就过了。。
代码
#include <bits/stdc++.h>
#define rin(i,a,b) for(register int i=(a);i<=(b);++i)
#define irin(i,a,b) for(register int i=(a);i>=(b);--i)
#define trav(i,a) for(register int i=head[a];i;i=e[i].nxt)
typedef long long LL;
using std::cin;
using std::cout;
using std::endl;
inline int read(){
int x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
const LL MOD=12345678;
int n,m,cnt;
int dx[8]={-1,-1,-1,0,1,1,1,0},dy[8]={-1,0,1,1,1,0,-1,-1};
int tot,X[10],Y[10],poscnt[1<<8],vis[5][10],tim;
LL f[30][1<<8],ans;
bool mp[5][10];
LL solve(){
f[0][0]=1,tot=0;
rin(i,1,n){
rin(j,1,m){
if(mp[i][j]){
++tot;
X[tot]=i,Y[tot]=j;
}
}
}
rin(i,0,(1<<tot)-1){
poscnt[i]=n*m;
++tim;
rin(j,1,tot){
if((i>>(j-1))&1){
rin(k,0,7){
int xx=X[j]+dx[k],yy=Y[j]+dy[k];
if(xx<1||xx>n||yy<1||yy>m) continue;
if(vis[xx][yy]!=tim){
vis[xx][yy]=tim;
--poscnt[i];
}
}
if(vis[X[j]][Y[j]]!=tim){
vis[X[j]][Y[j]]=tim;
--poscnt[i];
}
}
}
}
rin(i,1,n*m){
rin(j,0,(1<<tot)-1){
if(__builtin_popcount(j)>i) continue;
f[i][j]=0;
if(poscnt[((1<<tot)-1)^j]>=i) f[i][j]=f[i-1][j]*(poscnt[((1<<tot)-1)^j]-i+1)%MOD;
rin(k,1,tot){
if((j>>(k-1))&1){
f[i][j]=(f[i][j]+f[i-1][j^(1<<(k-1))])%MOD;
}
}
}
}
return f[n*m][(1<<tot)-1];
}
void dfs(int x,int y){
if(x==n+1){ans=(ans+((cnt&1)==1?-1:1)*solve()%MOD+MOD)%MOD;return;}
bool flag=true;
rin(i,0,7){
int xx=x+dx[i],yy=y+dy[i];
if(xx<1||xx>n||yy<1||yy>m) continue;
if(mp[xx][yy]){flag=false;break;}
}
if(y==m) dfs(x+1,1);
else dfs(x,y+1);
if(!flag||mp[x][y]) return;
mp[x][y]=true;
++cnt;
if(y==m) dfs(x+1,1);
else dfs(x,y+1);
mp[x][y]=false;
--cnt;
}
int main(){
n=read(),m=read();
rin(i,1,n){
rin(j,1,m){
char ch=getchar();
while(ch!='X'&&ch!='.') ch=getchar();
if(ch=='X'){
mp[i][j]=true;
rin(k,0,7){
int xx=i+dx[k],yy=j+dy[k];
if(xx<1||xx>n||yy<1||yy>m) continue;
if(mp[xx][yy]){
printf("0\n");
return 0;
}
}
}
}
}
dfs(1,1);
printf("%lld\n",ans);
return 0;
}
[BZOJ2669][CQOI2012]局部极小值:DP+容斥原理的更多相关文章
- [BZOJ2669] [cqoi2012]局部极小值
[BZOJ2669] [cqoi2012]局部极小值 Description 有一个n行m列的整数矩阵,其中1到nm之间的每个整数恰好出现一次.如果一个格子比所有相邻格子(相邻是指有公共边或公共顶点) ...
- bzoj2669[cqoi2012]局部极小值 容斥+状压dp
2669: [cqoi2012]局部极小值 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 774 Solved: 411[Submit][Status ...
- bzoj 2669 [cqoi2012]局部极小值 DP+容斥
2669: [cqoi2012]局部极小值 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 838 Solved: 444[Submit][Status ...
- BZOJ2669 [cqoi2012]局部极小值 状压DP 容斥原理
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ2669 题意概括 有一个n行m列的整数矩阵,其中1到nm之间的每个整数恰好出现一次.如果一个格子比所 ...
- bzoj2669 [cqoi2012]局部极小值 状压DP+容斥
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=2669 题解 可以发现一个 \(4\times 7\) 的矩阵中,有局部最小值的点最多有 \(2 ...
- 【BZOJ-2669】局部极小值 状压DP + 容斥原理
2669: [cqoi2012]局部极小值 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 561 Solved: 293[Submit][Status ...
- 【BZOJ 2669】 2669: [cqoi2012]局部极小值 (状压DP+容斥原理)
2669: [cqoi2012]局部极小值 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 667 Solved: 350 Description 有一 ...
- P3160 [CQOI2012]局部极小值 题解(状压DP+容斥)
题目链接 P3160 [CQOI2012]局部极小值 双倍经验,双倍快乐 解题思路 存下来每个坑(极小值点)的位置,以这个序号进行状态压缩. 显然,\(4*7\)的数据范围让极小值点在8个以内(以下示 ...
- P3160 [CQOI2012]局部极小值
题目 P3160 [CQOI2012]局部极小值 一眼就是状压,接下来就不知道了\(qwq\) 做法 我们能手玩出局部小值最多差不多是\(8,9\)个的样子,\(dp_{i,j}\)为填满\(1~i\ ...
随机推荐
- 小记-------linux scp 远程拷贝命令
//phoenix-4.10.0-HBase-1.2-server.jar 要拷贝的文件或文件夹 //root 当前用户 //192.148.21.1 远程机器路径, 也可以是域名. // $ ...
- Spring(九)--通知
Spring之Advice通知 Spring原生的经典模式 实现AOPadvice :通知 前置通知:在目标方法执行之前执行!不能改变方法的执行流程和结果! 实现MethodB ...
- Radio Button误区
在同一个父容器下,Radio Button控件默认只能选择一个,所以无需多余代码管控 如果将Radio Button的多个子对象存入NSArray列表,发现长度为0(巨坑),因此通过列表对其初始化不可 ...
- python日记:优化(SEO)狗学Python的日子(1)
一名优秀的程序员,在穿越单行道时也会确认双向的来车情况 ——道格拉斯.林德(Doug Linder) 大家可能好奇Python是什么东东,今天是小猿开始学习Python的第一天.周五在公司的时候收到了 ...
- JavaSE基础:集合类
JavaSE基础:集合类 简单认识类集 我们学习的是面向对象语言,而面向对象语言对事物的描述是通过对象体现的,为了方便对多个对象进行操作,我们就必须把这多个对象进行存储. 而要向存储多个对象,就不能是 ...
- mybatis中的动态代理应用(mapper对象)
-----------------UserMapper的配置信息--------------------- <?xml version="1.0" encoding=&quo ...
- js 学习三 Array
1.数组的长度 var sequence = [1, 1, 2, 3, 5, 8, 13]; sequence .length //7 2.字符串转换成数组 string.split() var my ...
- Xcode中常用的快捷键(原文链接http://www.cocoachina.com/ios/20141224/10752.html)
Xcode导航快捷键 1.工程导航器:Command+1 快速浏览代码.图片以及用户界面文件. 2.显示/隐藏导航器面板:Command+0 当你在对屏幕进行截图的时候可能会想要隐藏起与你感兴趣内容的 ...
- 扫描全能王 v5.13.0.20190916 去水印和广告版
说明 1.先安装1(安装完不要打开),再安装2,然后打开2,参考下图: 2.不要登录扫描全能王账号,否则会导致失败! 3.激活完成后可以卸载2 下载地址 城通网盘 蓝奏云(仅含1) 百度网盘 另外口袋 ...
- HashMap的相关面试题
HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道Hashtable和HashMap之间的区别,那么为何这道面试题如此 ...