题目链接:局部极小值

  这是一道\(dp\)好题。

  由于需要保证某些位置比周围都要小,那么我们可以从小到大把每个数依次填入,保证每个局部极小值填入之前周围都不能填,就只需要在加入的时候计数了。

  由于局部极小值最多只可能出现\(8\)个,所以我们可以直接状压当前所有局部极小值位置的状态。\(f_{i,S}\)表示当前填完了\(i\)个数,局部极小值状态为\(S\)的方案数。同时我们还需要一个\(cnt\)数组,\(cnt_S\)表示当局部极小值状态为\(S\)时有多少个位置不能填。

  这样转移方程就很显然了。可以从\(f_{i,S}\)转到\(f_{i+1,S}\),方案数为\(nm-i-cnt[S]\);或者直接在某个局部极小值位置上填一个数。

  但是这样会有问题,可能会导致某些非局部极小值的位置成为局部极小值。于是我们就可以枚举每个非局部极小值的位置是否是局部极小值,然后容斥掉即可。这样枚举的方案数看似很多,实际上最坏是不到\(2\times 10^4\)的。注意需要处理矩阵不合法的情况。

  下面贴代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout)
#define mod 12345678 using namespace std;
typedef long long llg; int zx[8]={-1,0,1,1,1,0,-1,-1};
int zy[8]={1,1,1,0,-1,-1,-1,0};
int n,m,cnt[1<<8],tol,fr[1<<8];
int f[29][1<<8],op[1<<8],ans;
int ci[5][8],ax[8],ay[8],la;
char s[5][8]; void work(int x,int y,int S,int z){
for(int k=0,i,j;k<8;k++){
i=x+zx[k],j=y+zy[k];
if(i>0 && i<=n && j>0 && j<=m){
if(!ci[i][j]) cnt[S]++;
ci[i][j]+=z;
}
}
} void dp(){
int now=1<<la;
for(int S=0;S<now;S++){
cnt[S]=fr[S];
for(int x=S,j;j=x&(-x),x;x-=j)
work(ax[op[j]+1],ay[op[j]+1],S,1);
for(int x=S,j;j=x&(-x),x;x-=j)
work(ax[op[j]+1],ay[op[j]+1],S,-1);
}
for(int i=0;i<=n*m;i++)
for(int S=0;S<now;S++) f[i][S]=0;
f[0][now-1]=1;
for(int i=0;i<n*m;i++){
for(int S=0,x;S<now;S++){
(f[i+1][S]+=f[i][S]*(n*m-i-cnt[S]))%=mod;
for(x=S;x;x-=x&(-x))
(f[i+1][S^(x&(-x))]+=f[i][S])%=mod;
}
}
if(tol) (ans-=f[n*m][0])%=mod;
else (ans+=f[n*m][0])%=mod;
} void print(){printf("0");exit(0);}
void dfs(int x,int y){
if(y==m+1) x++,y=1;
if(x==n+1){dp();return;}
bool ww=s[x][y]=='.';
for(int k=0;k<8;k++)
if(s[x+zx[k]][y+zy[k]]=='X') ww=0;
if(ww) s[x][y]='X',tol++;
if(s[x][y]=='X'){
la++,ax[la]=x,ay[la]=y;
dfs(x,y+1),la--;
}
if(ww) s[x][y]='.',tol--;
if(s[x][y]=='.') dfs(x,y+1);
} int main(){
File("a");
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++) scanf("%s",s[i]+1);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) if(s[i][j]=='X')
for(int k=0;k<8;k++)
if(s[i+zx[k]][j+zy[k]]=='X') print();
for(int i=0;i<(1<<8);i++) fr[i]=fr[i>>1]+(i&1);
for(int i=0;i<8;i++) op[1<<i]=i; dfs(1,1);
printf("%d",(ans+mod)%mod);
return 0;
}

BZOJ 2669 【CQOI2012】 局部极小值的更多相关文章

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

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

  2. BZOJ 2669 CQOI2012 局部极小值 状压dp+容斥原理

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2669 题意概述:实际上原题意很简洁了我就不写了吧.... 二话不说先观察一下性质,首先棋盘 ...

  3. ●BZOJ 2669 [cqoi2012]局部极小值

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2669 题解: 容斥,DP,DFS 先看看 dp 部分:首先呢,X的个数不会超过 8个.个数很 ...

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

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

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

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

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

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

  7. P3160 [CQOI2012]局部极小值

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

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

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

  9. BZOJ 2669 Luogu P3160 [CQOI2012]局部极小值 (容斥原理、DP)

    题目链接 (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=2669 (luogu) https://www.luogu.org/prob ...

随机推荐

  1. context、config

    Tomcat启动时已经创建了context,并使用它读取了web.xml中的参数,后台可以从context里获取参数 后台获取参数代码: ServletContext context = getSer ...

  2. R中双表操作学习[转载]

    转自:https://www.jianshu.com/p/a7af4f6e50c3 1.原始数据 以上是原有的一个,再生成一个新的: > gene_exp_tidy2 <- data.fr ...

  3. Vim/Vi的使用

     Vim 是vi的加强 Gvim图形化的vim Vim/Vi简介 Vim/Vi是一个功能强大的全屏幕文本编辑器,是Linux/Unix上最常用的文本编辑器,他们 的作用是建立,编辑,显示文本文件 Vi ...

  4. Vue.Js加入bootstrap及jquery,或加入其他插件vue-resource,vuex等

    .引入jquery 项目目录下输入 cnpm install jquery --save-dev      用npm下载jq依赖 若想加入其他js库,如vue-resource,执行命令cnpm in ...

  5. 关于gg_bd_ad_720x90.js和follow.js

    很多人对gg_bd_ad_720x90.js和follow.js 抱有疑问,这是个什么鬼? 我也迷惑了一阵子,今天偶然发现了这两个源文件. 大家一起欣赏下. 注意红色加粗代码. 1.follow.js ...

  6. memcached小试牛刀

    memcached安装 [root@localhost ~]# cd /usr/local/src [root@localhost src]#wget http://www.memcached.org ...

  7. hdu 6201 transaction transaction transaction

    https://vjudge.net/contest/184514#problem/H 题意: 一个商人为了赚钱,在城市之间倒卖商品.有n个城市,每个城市之间有且只有一条无向边连通.给出n个城市的货物 ...

  8. Python: attrgetter()函数: 排序不支持原生比较的对象

    问题: 想排序类型相同的对象,但是他们不支持原生的比较操作. answer: 内置的sorted()函数有一个关键字参数key,可传入一个callable对象给它 这个callabel对象对每个传入的 ...

  9. 在windows上构建LLVM 7.0.1

    关于在windows上构建LLVM,网上有不少文章,但都是互相抄来的,写作时极不认真,不是少这个,就是少那个,没有一篇是可以完整照着做下来的,实在气人. 本文的安装和配置过程,我亲自操作过好几遍,不惜 ...

  10. Linux基础命令---dumpe2fs

    dumpe2fs 显示ext2.ext3.ext4文件系统的超级快和块组信息.此命令的适用范围:RedHat.RHEL.Ubuntu.CentOS.SUSE.openSUSE.Fedora. 1.语法 ...