2669: [cqoi2012]局部极小值

Time Limit: 3 Sec  Memory Limit: 128 MB
Submit: 838  Solved: 444
[Submit][Status][Discuss]

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][sta]表示填了1-i个数,已经填完了状态为sta的方案数,然后剩下的

随便去填,但是这样会有一个问题,就是在其它'.'的位置,如果填成了局部最小解怎么办。

这样就会有多的方案算进去。

所以就要用容斥的方法去解决这个问题。

那f[i][sta]怎么算。

格式写不出来。

cnt的话就是暴力2*8*n*m*9 一次60000的复杂度而已,9代表判断周围。

f[i][j]=f[i-1][j](前面填了1-i中就已经填好了j这个状态,那么剩下就在cntj-(i-1))选一个,(因为cnt包含了

局部最小解个数),加上,所有的当前,填这一个最小解的方案数。因为填的数是不同的,所以是不同

状态。

复杂度是 2*8 *2*8*n*m*9差不多10000000这是极限

 #pragma GCC optimize(2)
#pragma G++ optimize(2)
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstdio>
#include<cstring> #define MOD 12345678
using namespace std;
const int dx[]={-,-,-,,,,,,};
const int dy[]={-,,,-,,-,,,};
inline int read()
{
int x=,f=;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-;ch=getchar();}
while(isdigit(ch)){x=(x<<)+(x<<)+ch-'';ch=getchar();}
return x*f;
} int n,m,ans;
char s[][]; int Calculate()
{
static pair<int,int> stack[];
static int cnt[<<],f[][<<];
int i,j,k,sta,top=;
memset(cnt,,sizeof cnt);
memset(f,,sizeof f);
for(i=;i<=n;i++)
for(j=;j<=m;j++)
if(s[i][j]=='X')
stack[++top]=pair<int,int>(i,j);
for(sta=;sta<<<top;sta++)
{
static bool unfilled[][];
memset(unfilled,,sizeof unfilled);
for(i=;i<=top;i++)
if(~sta&(<<i-))
unfilled[stack[i].first][stack[i].second]=true;
for(i=;i<=n;i++)
for(j=;j<=m;j++)
{
for(k=;k<;k++)
if(unfilled[i+dx[k]][j+dy[k]])
break;
if(k==)
cnt[sta]++;
}
}
f[][]=;
for(i=;i<=n*m;i++)
for(sta=;sta<<<top;sta++)
{
(f[i][sta]+=(long long)f[i-][sta]*max(cnt[sta]-i+,))%=MOD;
for(j=;j<=top;j++)
if(sta&(<<j-))
(f[i][sta]+=f[i-][sta^(<<j-)])%=MOD;
}
return f[n*m][(<<top)-];
}
void DFS(int x,int y,int cnt)
{
int i;
if(y==m+)
{
DFS(x+,,cnt);
return ;
}
if(x==n+)
{
(ans+=Calculate()*cnt)%=MOD;
return ;
}
DFS(x,y+,cnt);
for(i=;i<;i++)
if(s[x+dx[i]][y+dy[i]]=='X')
break;
if(i==)
{
s[x][y]='X';
DFS(x,y+,-cnt);
s[x][y]='.';
}
}
int main()
{
int i,j,k;
n=read(),m=read();
for(i=;i<=n;i++)
scanf("%s",s[i]+);
for(i=;i<=n;i++)
for(j=;j<=m;j++)
if(s[i][j]=='X')
for(k=;k<;k++)
if(s[i+dx[k]][j+dy[k]]=='X')
return puts(""),;
DFS(,,);
cout<<(ans+MOD)%MOD<<endl;
}

fi,j=fi−1,j∗C1cntj−i+1+∑k∈jfi−1,j−{k}

bzoj 2669 [cqoi2012]局部极小值 DP+容斥的更多相关文章

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

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

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

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

  3. bzoj 2169 连边 —— DP+容斥

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2169 就和这篇博客说的一样:https://blog.csdn.net/WerKeyTom_ ...

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

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

  5. bzoj 3622 DP + 容斥

    LINK 题意:给出n,k,有a,b两种值,a和b间互相配对,求$a>b$的配对组数-b>a的配对组数恰好等于k的情况有多少种. 思路:粗看会想这是道容斥组合题,但关键在于如何得到每个a[ ...

  6. 【BZOJ 4665】 4665: 小w的喜糖 (DP+容斥)

    4665: 小w的喜糖 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 94  Solved: 53 Description 废话不多说,反正小w要发喜 ...

  7. [Luogu P1450] [HAOI2008]硬币购物 背包DP+容斥

    题面 传送门:https://www.luogu.org/problemnew/show/P1450 Solution 这是一道很有意思的在背包里面做容斥的题目. 首先,我们可以很轻松地想到暴力做背包 ...

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

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

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

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

随机推荐

  1. CDN页面刷新接口定义[高升]

    一 . 任务 分发 工作流程步骤 1. 合作方按照高升定义的 json 数据格式向高升分发接口 post 任务,高升分发接口会根据接收情况即时反馈接收成功还是失败的结果.二 . 高升 分发 接口 定义 ...

  2. javascript函数创建

    函数声明 function add(a,b){ return a+b } 函数表达式 <!--一般函数表达式--> var add = function(){ } <!--立即声明函 ...

  3. python生产随机数案例

    法1: list =list(string.lowercase + string.uppercase) + [str(i) for i in range(10)]FH=('!','@','#','$' ...

  4. Intellij-工程目录下隐藏不想显示的文件和文件夹

    File-->Editor-->File Types

  5. linux指令--ls

    本篇博客转自http://www.cnblogs.com/peida/archive/2012/10/23/2734829.html,在原作者基础上做了修改和总结. ls命令是linux下最常用的命令 ...

  6. 豹哥嵌入式讲堂:ARM知识概要杂辑(4)- Cortex-M处理器性能指标

    1.处理器的性能指标 用于评价CPU的性能指标非常多,不同的性能侧重点下的测试标准可能得出的指标值不同,下面介绍嵌入式行业广泛使用的两个经典的测试标准. 1.1 Dhrystone标准 Dhrysto ...

  7. Part 7:自定义admin站点--Django从入门到精通系列教程

    该系列教程系个人原创,并完整发布在个人官网刘江的博客和教程 所有转载本文者,需在顶部显著位置注明原作者及www.liujiangblog.com官网地址. Python及Django学习QQ群:453 ...

  8. TCP/IP网络协议基础知识集锦[转]

    引言 本篇属于TCP/IP协议的基础知识,重点介绍了TCP/IP协议簇的内容.作用以及TCP.UDP.IP三种常见网络协议相关的基础知识. 内容 TCP/IP协议簇是由OSI七层模型发展而来的,之所以 ...

  9. vue调试神器vue-devtools安装

    vue-devtools安装 vue-devtools是一款用来调试Vue应用的Chrome插件,可极大提高开发者调试项目效率,接着我们说一下如何下载安装这个插件; 一. 从chrome商店直接下载安 ...

  10. Docker之镜像

    镜像(Images) 镜像是Docker的三大核心之一,类似于虚拟机,作用和虚拟机是一样的,唯独是组成部分会有些区别.简单的说如果我们想启动一个容器就必须要有镜像.docker运行容器前需要本地存在对 ...