分析

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

考虑子集反演(话说这个其实已经算是超集反演了吧还叫子集反演是不是有点不太合适),枚举题目给出位置集合的所有超集,计算让这些位置成为局部极小值,而其他位置随意的方案数,这个可以通过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. [转帖]站点部署,IIS配置优化指南

    站点部署,IIS配置优化指南 https://www.cnblogs.com/heyuquan/p/deploy-iis-set-performance-guide.html 挺值得学习的 毕竟之前很 ...

  2. yii框架RBAC權限管理

    基于角色的存取控制 (RBAC) 基于角色的存取控制 (RBAC) 提供了一个简单而强大的集中式存取控制机制. 详细的关于 RBAC 和诸多传统的存取控制方案对比的详情,请参阅 Wikipedia. ...

  3. Homebrew学习(六)之替换及重置homebrew、Homebred Core、Homebrew cask默认源

    替换及重置homebrew默认源 中科大源 替换官方源: // 替换brew.git: cd "$(brew --repo)" git remote set-url origin ...

  4. scrapy在settings中添加redis,可以实现断点续传

    DUPEFILTER_CLASS='scrapy_redis.dupefilter.RFPDupeFilter'SCHEDULER = 'scrapy_redis.scheduler.Schedule ...

  5. ShareSdk等等(三方登录与支付冲突问题)

    1.必须实现前两个方法,第三个方法照成支付回调有问题. //必须实现的方法 - (BOOL)application:(UIApplication *)application handleOpenURL ...

  6. kill - 终止进程

    SYNOPSIS(总览) kill[-ssignal|-p][-a]pid... kill -l [ signal ] DESCRIPTION (描述) kill 给指定进程发送指定信号. 如果没有指 ...

  7. libev个人问题解惑

    我们的游戏后端一直以来用的都是libev,之前尝试过去读源码,因为里面用了大量宏和自己也不够耐心的原因,一直没有看懂.这次终于痛下决心,一定要啃下它,于是在这个星期调整自己的工作学习方式(在读源码的过 ...

  8. 牛客练习赛47 A DongDong破密码 (异或性质,递推)

    链接:https://ac.nowcoder.com/acm/contest/904/A 来源:牛客网 DongDong破密码 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 1310 ...

  9. [工具] BurpSuite--Intruder功能

    BurpSuite--Intruder功能 0x00 配置说明 intruder是进行爆破的,基本流程是标注请求的爆破参数,然后配置字段,选择爆破方式进行爆破,下面来记录下工具的使用 选中intrud ...

  10. Mysql中event事件的入门

    Mysql中event事件的入门 主要涉及的知识点:mysql的存储过程.mysql的event事件调度. 参考资料: Qiao_Zhi的博客:[周期性执行事件]MySQL事件(Event)& ...