2669: [cqoi2012]局部极小值

Time Limit: 3 Sec  Memory Limit: 128 MB
Submit: 667  Solved: 350

Description

有一个nm列的整数矩阵,其中1到nm之间的每个整数恰好出现一次。如果一个格子比所有相邻格子(相邻是指有公共边或公共顶点)都小,我们说这个格子是局部极小值。
给出所有局部极小值的位置,你的任务是判断有多少个可能的矩阵。

Input

输入第一行包含两个整数nm(1<=n<=4, 1<=m<=7),即行数和列数。以下n行每行m个字符,其中“X”表示局部极小值,“.”表示非局部极小值。

Output

输出仅一行,为可能的矩阵总数除以12345678的余数。

Sample Input

3 2
X.
..
.X

Sample Output

60

HINT

Source

【分析】

  我好蠢啊。。。

  保证每个数各不相同,又有大小关系,那么、、数字从小到大填。

  其实局部极小值<=8的,这个可以状压,$f[i][j]$表示填了前i个数,局部极小值被填的状态是j的方案数。

  有:

  $f[i][j]=f[i-1][j]*(p[j]-i+1)+f[i-1][j-(1<<X)]$

  但是,还要保证一点是非极小值一定非极小,上面没有保证,

  所以枚举哪些非极小弄成了极小,容斥算出正确答案即可。

  复杂度?$O(dfs*n*m*8*2^8)$大概是这样吧。。数据很小嘛。。。

 #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define Mod 12345678
#define LL long long int a[][],num[][],p[];
int n,m;
int bx[]={,,,-,,,-,,-},
by[]={,,,,-,,-,-,};
char s[];
bool vis[][];
LL f[][],ans=; LL get_ans()
{
int cnt=;
for(int i=;i<=n;i++)
for(int j=;j<=m;j++) if(a[i][j]==) num[i][j]=++cnt;
for(int k=;k<=(<<cnt)-;k++)
{
for(int i=;i<=n;i++) for(int j=;j<=m;j++) vis[i][j]=;
for(int i=;i<=n;i++)
for(int j=;j<=m;j++) if(a[i][j]==&&((<<num[i][j]-)&k)==)
{
for(int l=;l<=;l++)
{
int nx=i+bx[l],ny=j+by[l];
vis[nx][ny]=;
}
}
p[k]=;
for(int i=;i<=n;i++)
for(int j=;j<=m;j++) if(vis[i][j]&&a[i][j]==) {p[k]++;vis[i][j]=;}
for(int i=;i<=cnt;i++) if((<<i-)&k) p[k]++;
}
memset(f,,sizeof(f));
f[][]=;
for(int i=;i<=n*m;i++)
for(int j=;j<=(<<cnt)-;j++)
{
f[i][j]=f[i-][j]*(p[j]-i+);f[i][j]%=Mod;
for(int k=;k<=cnt;k++) if((<<k-)&j)
{
f[i][j]+=f[i-][j-(<<k-)];
f[i][j]%=Mod;
}
}
return f[n*m][(<<cnt)-];
} void dfs(int x,int y,int f)
{
if(y==m+) {dfs(x+,,f);return;}
if(x==n+)
{
ans+=f*get_ans();
ans=(ans%Mod+Mod)%Mod;
return;
}
if(a[x][y]==) {dfs(x,y+,f);return;}
bool ok=;
for(int i=;i<=;i++)
{
int nx=x+bx[i],ny=y+by[i];
if(nx<||nx>n||ny<||ny>m) continue;
if(a[nx][ny]==) {ok=;break;}
}
if(ok)
{
a[x][y]=;
dfs(x,y+,-f);
a[x][y]=;
}
dfs(x,y+,f);
} int main()
{
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%s",s+);
for(int j=;j<=m;j++)
{
if(s[j]=='X') a[i][j]=;
else a[i][j]=;
}
}
for(int i=;i<=n;i++)
for(int j=;j<=m;j++) if(a[i][j]==)
{
for(int k=;k<=;k++)
{
int nx=i+bx[i],ny=j+by[i];
if(nx<||nx>n||ny<||ny>m) continue;
if(a[nx][ny]==) {printf("0\n");return ;}
}
}
// memset(vis,1,sizeof(vis));
dfs(,,);
printf("%lld\n",ans);
return ;
}

2017-04-06 10:08:51

【BZOJ 2669】 2669: [cqoi2012]局部极小值 (状压DP+容斥原理)的更多相关文章

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

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

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

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

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

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

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

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

  5. 【uoj#37/bzoj3812】[清华集训2014]主旋律 状压dp+容斥原理

    题目描述 求一张有向图的强连通生成子图的数目对 $10^9+7$ 取模的结果. 题解 状压dp+容斥原理 设 $f[i]$ 表示点集 $i$ 强连通生成子图的数目,容易想到使用总方案数 $2^{sum ...

  6. 【bzoj2560】串珠子 状压dp+容斥原理

    题目描述 有 $n$ 个点,点 $i$ 和点 $j$ 之间可以连 $0\sim c_{i,j}$ 条无向边.求连成一张无向连通图的方案数模 $10^9+7$ .两个方案不同,当且仅当:存在点对 $(i ...

  7. BZOJ.4145.[AMPPZ2014]The Prices(状压DP)

    BZOJ 比较裸的状压DP. 刚开始写麻烦惹... \(f[i][s]\)表示考虑了前\(i\)家商店,所买物品状态为\(s\)的最小花费. 可以写求一遍一定去\(i\)商店的\(f[i]\)(\(f ...

  8. BZOJ.3058.四叶草魔杖(Kruskal 状压DP)

    题目链接 \(2^{16}=65536\),可以想到状压DP.但是又有\(\sum A_i\neq 0\)的问题.. 但是\(2^n\)这么小,完全可以枚举所有子集找到\(\sum A_i=0\)的, ...

  9. bzoj 5299: [Cqoi2018]解锁屏幕 状压dp+二进制

    比较简单的状压 dp,令 $f[S][i]$ 表示已经经过的点集为 $S$,且最后一个访问的位置为 $i$ 的方案数. 然后随便转移一下就可以了,可以用 $lowbit$ 来优化一下枚举. code: ...

  10. 4455: [Zjoi2016]小星星|状压DP|容斥原理

    OrzSDOIR1ak的晨神 能够考虑状压DP枚举子集,求出仅仅保证连通性不保证一一相应的状态下的方案数,然后容斥一下就是终于的答案 #include<algorithm> #includ ...

随机推荐

  1. [php]apache的权限解释

    格式如下: <Directory d:/...> Order allow,deny Allow from all Allow from 127.0.0.1 Deny from 110.0. ...

  2. How to reset XiaoMi bluetooth headphone Youth edition.

    To reset the speaker 1. Long press the phone call button to shut off the speaker 2. Connect the char ...

  3. C语言二分查找

    #include <stdio.h> /* 二分查找条件: 1.有序序列 2.数据在数组中 */ int baseBinarySearch(int a[],int h,int k) { ; ...

  4. 2017 ACM暑期多校联合训练 - Team 4 1007 HDU 6073 Matching In Multiplication (模拟)

    题目链接 Problem Description In the mathematical discipline of graph theory, a bipartite graph is a grap ...

  5. kendo method:destroy 解决有些在kendo.all.js 的js 库里报错问题

    首先,不得不承认,kendo UI 是个不错的东西,特别对于一个前端开发到行不足的程序猿来说.而在我们使用过程中貌似还是会遇到各种奇怪的问题.比如我们会经常用到对一些控件进行重赋值. destroy ...

  6. isolation forest进行异常点检测

    一.简介 孤立森林(Isolation Forest)是另外一种高效的异常检测算法,它和随机森林类似,但每次选择划分属性和划分点(值)时都是随机的,而不是根据信息增益或者基尼指数来选择.在建树过程中, ...

  7. 巅峰极客CTF writeup[上]

    经验教训 1.CTF不比实战,最好不要死磕.死磕就输了.我就是死磕在缓存文件死的.真的惭愧: 2.对于flag的位置不要太局限于web目录下,如果是命令执行直接上find / -name flag*: ...

  8. 【swupdate文档 四】SWUpdate:使用默认解析器的语法和标记

    SWUpdate:使用默认解析器的语法和标记 介绍 SWUpdate使用库"libconfig"作为镜像描述的默认解析器. 但是,可以扩展SWUpdate并添加一个自己的解析器, ...

  9. The algorithm of entropy realization

    近似熵的一种快速实用算法 Pincus提出的近似熵算法中有很多冗余的计算,效率低,速度慢,不利于实际应用,洪波等人在定义的基础上引入二值距离矩阵的概率,提出了一种实用快速的算法. function A ...

  10. highcharts自定义导出文件格式(csv) highcharts的一些使用心得

    highcharts是国外的一个图表插件,包括各种数据图形展示,柱形图,线性图等等,是手机端和pc端最好的图表插件之一,相比于百度的echarts更加轻便和易懂.链接http://www.hchart ...