上课讲的一道题,感觉也挺厉害的~正解是容斥 + 状压dp。首先我们容易发现一共可能的局部最小值数量是十分有限的,最多也只有 \(8\) 个。所以我们可以考虑状压。

  建立出状态 \(f[i][j]\) 表示我们从小到大往方格当中填数,填完前\(i\) 个数之后,局部最小值的填充状态为 \(j\) 的方案数。这样一共有两种转移 :

\(f[i][j] = f[i - 1][j] * (g[j] - ((i - 1) - |j|)) + \sum f[i][j']\)

  分别表示加入了一个局部最小值 / 其他位置的值。其中的 \(g[j]\) 表示在 \(j\) 的状态下可以放入的非局部最小值的个数。但这样做出来还是不够的——我们虽然保证了要求的位置上一定是局部最小值,但是其余的位置上也有可能是局部最小值,而这是不符合要求的。我们考虑用容斥来处理,用全集 - 至少有一个非局部最小值成为了局部最小值的方案数,+至少两个,-至少三个……

  每一个dfs出来的状态都用上面的方法dp加入到答案中去就可以了。

#include <bits/stdc++.h>
using namespace std;
#define maxn 400
#define maxm 500
#define int long long
#define mod 12345678
int n, m, N, tot, cnt, ans;
int Map[maxn][maxn], id[maxn][maxn];
int f[maxn][maxm], g[maxm], T;
int dx[] = {-, , , -, , -, , };
int dy[] = {-, -, -, , , , , }; struct node
{
int x, y;
}P[maxn]; void Up(int& x, int y) { x = (x + y) % mod; } int DP()
{
int K = ( << tot) - ;
for(int k = ; k <= K; k ++)
{
g[k] = ; int tem = k, len = ;
while(tem) len += (tem & ), tem >>= ;
for(int i = ; i <= n; i ++)
for(int j = ; j <= m; j ++)
{
int flag = ; if(Map[i][j]) continue;
for(int l = ; l < ; l ++)
{
int x = i + dx[l], y = j + dy[l];
if(Map[x][y] && !(( << (id[x][y] - )) & k))
{ flag = ; break; }
}
if(!flag) g[k] ++;
}
g[k] += len;
}
memset(f, , sizeof(f)); f[][] = ;
for(int i = ; i <= N; i ++)
for(int j = ; j <= K; j ++)
{
Up(f[i][j], f[i - ][j] * (g[j] - (i - )));
int tem = j, len = ;
while(tem) len ++, tem >>= ;
for(int k = ; k < len; k ++)
if(j & ( << k)) Up(f[i][j], f[i - ][j ^ ( << k)]);
}
return f[N][K];
} void DFS(int x, int y)
{
if(y > m) x += , y = ;
if(x > n)
{
if((tot - cnt) & ) ans = (ans - DP() + mod) % mod;
else ans = (ans + DP()) % mod;
return;
}
DFS(x, y + );
if(Map[x][y]) return;
for(int i = ; i < ; i ++)
if(Map[x + dx[i]][y + dy[i]]) return;
Map[x][y] = , P[++ tot].x = x, P[tot].y = y; id[x][y] = tot;
DFS(x, y + );
tot --, Map[x][y] = , id[x][y] = ;
} signed main()
{
scanf("%lld%lld", &n, &m); N = n * m;
for(int i = ; i <= n; i ++)
for(int j = ; j <= m; j ++)
{
char c; cin >> c;
if(c == 'X')
{
P[++ tot].x = i, P[tot].y = j;
Map[i][j] = , id[i][j] = tot;
}
}
cnt = tot;
for(int i = ; i <= tot; i ++)
{
T |= ( << (i - ));
for(int j = ; j < ; j ++)
if(Map[P[i].x + dx[j]][P[i].y + dy[j]])
{
printf("");
return ;
}
}
DFS(, );
printf("%lld\n", ans);
return ;
}

【题解】CQOI2012局部最小值的更多相关文章

  1. [BZOJ2669][CQOI2012]局部最小值(容斥+状压DP)

    发现最多有8个限制位置,可以以此为基础DP和容斥. $f_{i,j}=f_{i-1,j}\times (cnt_j-i+1)+\sum_{k\subset j} f_{i-1,k}$ $cnt_j$表 ...

  2. 【noip模拟】局部最小值

    TimeLimit: 1000ms               MemoryLimit: 256MB Description 有一个n行m列的整数矩阵,其中1到n×m之间的每个整数恰好出现一次.如果一 ...

  3. 关于过拟合、局部最小值、以及Poor Generalization的思考

    Poor Generalization 这可能是实际中遇到的最多问题. 比如FC网络为什么效果比CNN差那么多啊,是不是陷入局部最小值啊?是不是过拟合啊?是不是欠拟合啊? 在操场跑步的时候,又从SVM ...

  4. [nowCoder] 局部最小值位置

    定义局部最小的概念.arr长度为1时,arr[0]是局部最小.arr的长度为N(N>1)时,如果arr[0]<arr[1],那么arr[0]是局部最小:如果arr[N-1]<arr[ ...

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

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

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

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

  7. 【bzoj2669】[cqoi2012]局部极小值 容斥原理+状压dp

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

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

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

  9. Mathematica 中 Minimize函数无法找到全局最小值时的解决方法

    一直使用Minimize来找到指定约束下的函数的最小值,最近发现在一个非线性函数中使用Minimize无法提供一个"全局"最小值(使用Mathematica只是用来验证算法的,所以 ...

随机推荐

  1. IAR环境下编译CC2640入门开发

    1. 安装SDK包,之后导入AIR里面,编译报错 看样子似乎是xdc工具的路径配置不对,进入路径配置对话窗 开始配置 配置完之后,重新编译 Fatal Error[Pe1696]: cannot op ...

  2. 阅读笔记《JavaScript高级程序设计》

    0. 严格模式 "user strict" (1整个脚本顶部,2函数体顶部) 1. 数据类型 undefined -- 未定义 boolean string number obje ...

  3. 两分钟了解Docker的优势

    本文来自网易云社区 我们主要从Docker对业务架构和生产实践的角度来分析. 随着业务规模的逐渐扩大,产品复杂度也随着增加,企业需要解决快速迭代.高可靠和高可用等问题,一个自然的选择是服务化的拆分,把 ...

  4. 2019年猪年海报PSD模板-第七部分

    14套精美猪年海报,免费猪年海报,下载地址:百度网盘,https://pan.baidu.com/s/1pE3X9AYirog1W8FSxbMiAQ              

  5. 结合BeautifulSoup和hackhttp的爬虫实例

    网页页数的改变 headers头不添加

  6. JDK11安装后,环境变量的坑

    安装了最新的JDK11,安装完后设置环境变量,打开CMD,没生效 检查了3遍,都没发现问题,在PATH中将JAVA设置移到第一也不行 最后偶然发现,在点击如图右下的‘编辑文本’,用文本方式编辑时,发现 ...

  7. 题解 CF682C 【Alyona and the Tree】

    简单搜索题,我们每找到一组不满足题目给出条件的点和边就将其整个子树删除,然后最终答案加上该子树的大小即可.注意,搜索的时候如果当前的边权和sum已经为负了,应该将其改为0(可以想想为什么) 注:题目翻 ...

  8. java 流 文件 IO

    Java 流(Stream).文件(File)和IO Java.io 包几乎包含了所有操作输入.输出需要的类.所有这些流类代表了输入源和输出目标. Java.io 包中的流支持很多种格式,比如:基本类 ...

  9. [SHELL]结构化命令之条件语句

    1.if-then语句  #!/bin/bash username="root" if grep $username /etc/passwd then echo "the ...

  10. CsvHelper文档-2读

    CsvHelper文档-2读 这个库默认不需要做任何设置就可以很容易的使用它.如果你的类属性名称直接匹配csv的标题名称,那么可以按照下面的实例来用: (以下所有的代码都需要引用using csvhe ...