bzoj 2669 [cqoi2012]局部极小值 DP+容斥
2669: [cqoi2012]局部极小值
Time Limit: 3 Sec Memory Limit: 128 MB
Submit: 838 Solved: 444
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
X.
..
.X
Sample Output
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+容斥的更多相关文章
- BZOJ 2669 CQOI2012 局部极小值 状压dp+容斥原理
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2669 题意概述:实际上原题意很简洁了我就不写了吧.... 二话不说先观察一下性质,首先棋盘 ...
- ●BZOJ 2669 [cqoi2012]局部极小值
题链: http://www.lydsy.com/JudgeOnline/problem.php?id=2669 题解: 容斥,DP,DFS 先看看 dp 部分:首先呢,X的个数不会超过 8个.个数很 ...
- bzoj 2169 连边 —— DP+容斥
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2169 就和这篇博客说的一样:https://blog.csdn.net/WerKeyTom_ ...
- 【BZOJ 2669】 2669: [cqoi2012]局部极小值 (状压DP+容斥原理)
2669: [cqoi2012]局部极小值 Time Limit: 3 Sec Memory Limit: 128 MBSubmit: 667 Solved: 350 Description 有一 ...
- bzoj 3622 DP + 容斥
LINK 题意:给出n,k,有a,b两种值,a和b间互相配对,求$a>b$的配对组数-b>a的配对组数恰好等于k的情况有多少种. 思路:粗看会想这是道容斥组合题,但关键在于如何得到每个a[ ...
- 【BZOJ 4665】 4665: 小w的喜糖 (DP+容斥)
4665: 小w的喜糖 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 94 Solved: 53 Description 废话不多说,反正小w要发喜 ...
- [Luogu P1450] [HAOI2008]硬币购物 背包DP+容斥
题面 传送门:https://www.luogu.org/problemnew/show/P1450 Solution 这是一道很有意思的在背包里面做容斥的题目. 首先,我们可以很轻松地想到暴力做背包 ...
- P3160 [CQOI2012]局部极小值 题解(状压DP+容斥)
题目链接 P3160 [CQOI2012]局部极小值 双倍经验,双倍快乐 解题思路 存下来每个坑(极小值点)的位置,以这个序号进行状态压缩. 显然,\(4*7\)的数据范围让极小值点在8个以内(以下示 ...
- bzoj2669 [cqoi2012]局部极小值 状压DP+容斥
题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=2669 题解 可以发现一个 \(4\times 7\) 的矩阵中,有局部最小值的点最多有 \(2 ...
随机推荐
- mybatis_helloWorld_sequence图(3)
摘录自:http://blog.csdn.net/y172158950/article/details/17006127 1. 依据resource获取Reader的sequence图 String ...
- RAC和单节点数据库的区别有哪些?RAC最有用的功能是什么?
区别 (1)RAC有2个以上的实例,单节点只有1个实例 (2)RAC具有实例级别的高可用 (3)实例与实例之间通过内联网络交换数据,单节点不可 (4)RAC每个节点都有自己套SGA.后台进程.redo ...
- jQuery hover() 方法
$("p").hover(function(){ $("p").css("background-color","yellow&qu ...
- linux mysql 修改 UTF-8编码
版本大于5.5 [mysqld]下添加的应该为: character-set-server=utf8 collation-server=utf8_general_ci 版本小于5.5 [cli ...
- SSMS 2005 连接 SQL SERVER 2008问题
用本机的 Microsoft SQL Server Management Studio 2005 客户端连接数据库服务器时报错:"This version of Microsoft SQL ...
- Hibernate (三)
1 一对多的单向 示例:一个已经存在的学生,新建一个班级,然后将该学生加入到该班级之下 设置inverse="false" <?xml version="1.0&q ...
- Ubuntu中使用dnw工具:没有找到/dev/secbulk0
Ubuntu中使用dnw动机: 一. 之前没有用ubuntu中的dnw,想试试. 二. 因为换了win10系统,怕搞不定win10中dnw的驱动,想着在ubuntu中不用禁用数字签名啥的比较省心.(事 ...
- nginx配置中root与alias的区别
nginx指定文件路径有两种方式root和alias,这两者的用法区别,使用方法总结了下,方便大家在应用过程中,快速响应.root与alias主要区别在于nginx如何解释location后面的uri ...
- TCP全连接队列和半连接队列已满之后的连接建立过程抓包分析[转]
最近项目需要做单机100万长连接与高并发的服务器,我们开发完服务器以后,通过自己搭的高速压测框架压测服务端的时候,发生了奇怪的现象,就是服务端莫名其妙的少接收了连接,造成了数据包的丢失,通过网上查资料 ...
- python并发编程之多进程(实现)
一.multipricessing模块的介绍 python中的多线程无法利用多核优势,如果想要充分的使用多核CPU资源,在python中大部分情况下需要用多线程,python提供了multiproce ...