分析

题目要求有且只有一些位置是局部极小值。有的限制很好处理,但是只有嘛,嗯......

考虑子集反演(话说这个其实已经算是超集反演了吧还叫子集反演是不是有点不太合适),枚举题目给出位置集合的所有超集,计算让这些位置成为局部极小值,而其他位置随意的方案数,这个可以通过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+容斥原理的更多相关文章

  1. [BZOJ2669] [cqoi2012]局部极小值

    [BZOJ2669] [cqoi2012]局部极小值 Description 有一个n行m列的整数矩阵,其中1到nm之间的每个整数恰好出现一次.如果一个格子比所有相邻格子(相邻是指有公共边或公共顶点) ...

  2. bzoj2669[cqoi2012]局部极小值 容斥+状压dp

    2669: [cqoi2012]局部极小值 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 774  Solved: 411[Submit][Status ...

  3. bzoj 2669 [cqoi2012]局部极小值 DP+容斥

    2669: [cqoi2012]局部极小值 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 838  Solved: 444[Submit][Status ...

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

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

  5. bzoj2669 [cqoi2012]局部极小值 状压DP+容斥

    题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=2669 题解 可以发现一个 \(4\times 7\) 的矩阵中,有局部最小值的点最多有 \(2 ...

  6. 【BZOJ-2669】局部极小值 状压DP + 容斥原理

    2669: [cqoi2012]局部极小值 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 561  Solved: 293[Submit][Status ...

  7. 【BZOJ 2669】 2669: [cqoi2012]局部极小值 (状压DP+容斥原理)

    2669: [cqoi2012]局部极小值 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 667  Solved: 350 Description 有一 ...

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

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

  9. P3160 [CQOI2012]局部极小值

    题目 P3160 [CQOI2012]局部极小值 一眼就是状压,接下来就不知道了\(qwq\) 做法 我们能手玩出局部小值最多差不多是\(8,9\)个的样子,\(dp_{i,j}\)为填满\(1~i\ ...

随机推荐

  1. BZOJ 4857 反质数序列

    题面 奇数+奇数一定不是质数(1+1除外),偶数+偶数一定不是质数,质数只可能出现在偶数+奇数中 把所有的点排成两列,权值为奇数的点在左边,权值为偶数的在右边 如果左边的点x+右边的点y是质数,我们就 ...

  2. python简介与简单入门

    1.计算机基础 计算机组成: 输入输出设备内. 存储器 .cpu .电源 .显卡 中央处理器(cpu) 处理各种数据 相当于人的大脑 内存 存储数据 相当于临时记忆 硬盘 存储数据 相当于人的永久记忆 ...

  3. Linux 问题集

    解决E: Encountered a section with no Package: header错误 我的ubuntu机器上出现下面这个错误. Reading package lists... E ...

  4. Python 常用库(随时补充)

    1. Python-RSA使用手册 英文文档见Python-RSA使用手册,主要介绍了Python-RSA的消息的加密解密.文件的加密解密以及签名的方法. Installation 使用pip ins ...

  5. webpack3 打包

    1. 基于 webpack 3.0 2.步骤.说明 2.1 webpack 本地初始化.安装基本包 npm init         >  package.json npm i  webpack ...

  6. 集合类Hash Set,LinkedHashSet,TreeSet

    集合(set)是一个用于存储和处理无重复元素的高效数据结构.映射表(map)类似于目录,提供了使用键值快速查询和获取值的功能. HashSet类是一个实现了Set接口的具体类,可以使用它的无参构造方法 ...

  7. Spring-data-jpa n+1问题

    Spring-data-jpa的n+1问题 当我们使用JPA提供给我们的find方法时,如果查询出来的对象关联着另外10个对象,那么JPA将会发送1+10次查询(这个对象本身要查询一次,然后每个关联对 ...

  8. 目标检测数据库 PASCAL 格式的 Ground Truth 的解析函数

    最近在做一个目标检测算法,训练时用到了 bootstrap 策略,于是我将PASCAL的 Ground Truth 格式的读取函数从 Matlab 改写为 C++.PASCAL 的标注格式为: # P ...

  9. python-函数4(递归、高阶函数)

    python-函数4(递归.高阶函数) 递归 在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数. 递归特性: 1. 递归必须有一个明确的结束条件 2. 每次进入更深一 ...

  10. Vue基础第四章 - v-bind指令

    1.v-bind指令介绍 在前端开发过程中最常做的事莫过于class类名的绑定与style内联样式的修改,Vue中使用v-bind指令来实现这两个需求,在第二章中给出过简单的示例,下面我们来看一下v- ...