上课讲的一道题,感觉也挺厉害的~正解是容斥 + 状压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. Java String源码解析

    public final class String implements java.io.Serializable, Comparable<String>, CharSequence { ...

  2. 问题集 - console.log在IE下不可用

    js中添加如下一段代码即可. if(!window.console){ window.console = {}; } if(!window.console.log){ window.console.l ...

  3. iOS UIWebView加载时添加进度条01

    标注:此框架仅适合UIWebView  对iOS8后新出的WKWebView不适用,当然,你可以尝试修改框架里的几个代理方法. 框架是:NJKWebViewProgress 导入头文件 #import ...

  4. 「日常训练」Maximum Multiple(HDU-6298)

    题意与分析 一开始以为是一条高深的数学题,跳过去了,后来查其他题目的代码的时候无意看到,一看emmmmmm 稍微思考一下就有了.\(1=\frac{1}{3}+\frac{1}{3}+\frac{1} ...

  5. Unity初探之黑暗之光(1)

    Unity初探之黑暗之光(1) 1.镜头拉近 public float speed=10f;//镜头的移动速度 ;//镜头的结束位置 // Update is called once per fram ...

  6. 【hidden】微信小程序hidden属性使用示例

    hidden属性用于隐藏标签,代码示例: <view hidden="{{!statusTag}}">我出来了~</view> <button bin ...

  7. hihocoder刷题 扫雷游戏

    题目1 : 扫雷游戏 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 给定一个N × N的方格矩阵,其中每个格子或者是'*',表示该位置有一个地雷:或者是'.',表示该位 ...

  8. CSP201409-2:画图

    引言:CSP(http://www.cspro.org/lead/application/ccf/login.jsp)是由中国计算机学会(CCF)发起的"计算机职业资格认证"考试, ...

  9. 「雅礼集训 2017 Day1」市场 (线段树除法,区间最小,区间查询)

    老师说,你们暴力求除法也整不了多少次就归一了,暴力就好了(应该只有log(n)次) 于是暴力啊暴力,结果我归天了. 好吧,在各种题解的摧残下,我终于出了一篇巨好看(chou lou)代码(很多结构体党 ...

  10. oracle数据库之PL/SQL 流程控制语句

    介绍 PL/SQL 的流程控制语句, 包括如下三类: 1.控制语句: IF 语句 2.循环语句: LOOP 语句, EXIT 语句 3.顺序语句: GOTO 语句, NULL 语句 一 条件语句 IF ...