2669: [cqoi2012]局部极小值

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

Description

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

Input

输入第一行包含两个整数n和m(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. Spring+JTA+Atomikos+mybatis分布式事务管理

    我们平时的工作中用到的Spring事务管理是管理一个数据源的.但是如果对多个数据源进行事务管理该怎么办呢?我们可以用JTA和Atomikos结合Spring来实现一个分布式事务管理的功能.了解JTA可 ...

  2. ESP8266重点知识

    每一个mcu对应一个库文件,所以每次上传烧写arduino都需要对应的库文件,修改起来很麻烦,不如记录下来每次的库文件,或者每次都自动生成.这样效果最佳.而且我想应该是比较稳定的, 现在比较朦胧一个问 ...

  3. 洛谷P1233 [木棍加工]

    主要思路: 这道题一眼看过去就可以贪心.. 首先可以按L排序.. 显然排序之后我们就可以抛开L不管了.. 然后就可以愉快的贪心了.. 细节: 这道题可以看成用 最少的合法序列(详见原题) 装下所有木棍 ...

  4. JavaScript数组的22种方法

    原文:http://www.cnblogs.com/xiaohuochai/p/5682621.html javascript中数组的22种方法   前面的话 数组总共有22种方法,本文将其分为对象继 ...

  5. css 对图片颜色的处理

    很久很久以前,在一个项目中,经理要求对一个图片做模糊处理.第一反应是这个要找 ui 给个模糊图片.可当时 ui 不在呀,项目又着急,只能自己搞.我一个前端,ps 技术实在不咋的,叫我切切图还可以,叫我 ...

  6. 重新认识AWS

    Amazon Web Services早期logo: 现在的logo: 一.背景Amazon Web Services,简称AWS.目前世界第一大云计算厂商,AWS 云在全球 18 个地理地区内运营着 ...

  7. zabbix_sender用法实例

    环境centos6.8 zabbix版本3.2.4 需求: 要远程监控一台服务器A,但只能通过远程服务器连接本地服务器B,但B不能主动连A(因为A没有固定公网ip) 使用了zabbix_agent的a ...

  8. KVM虚拟机绑定物理CPU进行性能调优

    PS:前提是虚拟cpu总个数不多于物理cpu总个数.   绑定方法: 虚拟机的虚拟cpu有1个,实体机物理cpu有8个,可以通过以下方式绑定cpu,绑定的动作不一定要在虚机启动时,可以在任何时候: 绑 ...

  9. Python selenium 一个节点两个关联input

    HTML代码: 一个节点两个关联input  多出现于密码框 先需要模拟点击进入第一个input,才能激活第二个input. 代码: driver.find_element_by_name('Text ...

  10. aop难点解析。

    静态织入和动态织入的区别? 需求示例:假设有一个包,一个包当中有一个方法,我们想在这个方法的前后,加上环绕. 那么怎么加呢? 把知道的都说一遍. 1.建立JsonService 2.建立JSONASP ...