[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\ ...
随机推荐
- phpstorm 不能选择 php language level
最近需要更改phpstorm中的php language level发现更改不了 解决方法是在PHP 下面的Composer中勾选了同步 composer php版本的原因 取消勾选,点击应用就可以了
- ubuntu中安装Python3.7
一. 源码安装: 1. 官网源码下载: Python官网:https://www.python.org/downloads/ setuptools官网:https://pypi.org/project ...
- 会引起全表扫描的几种SQL 以及sql优化 (转)
出处: 查询语句的时候尽量避免全表扫描,使用全扫描,索引扫描!会引起全表扫描的几种SQL如下 1.模糊查询效率很低: 原因:like本身效率就比较低,应该尽量避免查询条件使用like:对于like ‘ ...
- 【BZOJ-4289】Tax 最短路 + 技巧建图(化边为点)
题意 给出一个N个点M条边的无向图,经过一个点的代价是进入和离开这个点的两条边的边权的较大值,求从起点1到点N的最小代价.起点的代价是离开起点的边的边权,终点的代价是进入终点的边的边权N<=10 ...
- npm工作流 与webpack 分同环境配置
npm:http://www.ruanyifeng.com/blog/2016/10/npm_scripts.html process.env.npm_lifecycle_event process. ...
- shell脚本之删除内容相同的重复文件
#!/bin/bash #!当前文件夹下,删除内容相同的重复文件,只保留重复文件中的一个. ls -lS --time-style=long-iso | awk 'BEGIN{ getline;get ...
- 2019-11-29-VisualStudio-使用新项目格式快速打出-Nuget-包
title author date CreateTime categories VisualStudio 使用新项目格式快速打出 Nuget 包 lindexi 2019-11-29 10:15:25 ...
- HashMap的相关面试题
HashMap的工作原理是近年来常见的Java面试题.几乎每个Java程序员都知道HashMap,都知道哪里要用HashMap,知道Hashtable和HashMap之间的区别,那么为何这道面试题如此 ...
- PHP WEB 引擎缓存加速优化
PHP 缓存加速器介绍 操作码缓存 请求一个 PHP 程序时,PHP 引擎会解析程序,并且将编译码作为特定操作码.这是要执行的代 码的一种二进制表示形式.随后,此操作码有 PHP 引擎执行并丢弃.操作 ...
- PHP出现502解决方案
nginx 出现 502 有很多原因,但大部分原因可以归结为资源数量不够用,也就是说后端 php-fpm 处 理有问题,nginx 将正确的客户端请求发给了后端的 php-fpm 进程,但是因为 ph ...