bzoj 2669 状压DP
因为最多有8个'X',所以我们可以用w[i][s]来表示现在我们填了前i个数,填的X的为S,因为每次新加进来的数都不影响前面的最小值,所以我们可以随便添加,这样就有了剩下所有位置的方案,每次都这样转移。
但是这样会造成不是规定的地方出现局部最小值的情况,对于这样的情况,我们只需要枚举所有可能成为局部最小值的不合法状态来做容斥就可以了。
反思:这道题的容斥开始写错了,本来应该是判奇偶来判断正负,写成了全是负的,还是A了,应该是后面的容斥没有合法方案所以符号无所谓的关系,真是rp++。
/**************************************************************
Problem: 2669
User: BLADEVIL
Language: C++
Result: Accepted
Time:0 ms
Memory:928 kb
****************************************************************/
//By BLADEVIL
#include <cstdio>
#include <cstring>
#define d39 12345678
#define get(x) ((x&1)?-1:1)
using namespace std;
char s[][];
int map[][],flag[][],w[][],X[],Y[],tot[],tmp[][];
int ans,sum,n,m;
const int go[][]={{-,-},{-,},{-,},{,},{,},{,},{,-},{,-}};
int solve() {
int cnt=,x,y,flag;
for (int i=;i<=n;i++)
for (int j=;j<=m;j++) if (map[i][j]) X[cnt]=i,Y[cnt++]=j;
for (int p=;p<(<<cnt);p++) {
tot[p]=;
memset(tmp,,sizeof tmp);
for (int i=;i<cnt;i++) if (p&(<<i)) tmp[X[i]][Y[i]]=;
for (int i=;i<=n;i++)
for (int j=;j<=m;j++) if (!tmp[i][j]) {
flag=;
for (int k=;k<&&flag;k++) {
x=i+go[k][],y=j+go[k][];
if (x<||x>n||y<||y>m) continue;
if (tmp[x][y]) flag=;
}
if (flag) tot[p]++;
}
}
memset(w,,sizeof w);
w[][]=;
int opp;
for (int i=;i<=sum;i++) {
for (int p=;p<(<<cnt);p++) if (w[i-][p]) {
opp=;
for (int j=;j<cnt;j++) if (!(p&(<<j)))
opp|=(<<j),(w[i][p|(<<j)]+=w[i-][p])%=d39;
(w[i][p]+=w[i-][p]*(tot[opp]-(i-))%d39)%=d39;
}
}
return w[sum][(<<cnt)-];
}
void ie(int x,int y,int t){
map[x][y]=;
int i,j,ret;
for (int k=;k<;k++) {
i=x+go[k][],j=y+go[k][];
if (i<||i>n||j<||j>m) continue;
if (flag[i][j]) continue;
flag[i][j]=t;
}
ret=solve();
ans=(ans+get(t)*ret)%d39;
for (j=y+;j<=m;j++) if (flag[x][j]==) ie(x,j,t+);
for (i=x+;i<=n;i++)
for (j=;j<=m;j++) if (flag[i][j]==) ie(i,j,t+);
map[x][y]=;
for (int k=;k<;k++) {
i=x+go[k][],j=y+go[k][];
if (i<||i>n||j<||j>m) continue;
if (flag[i][j]==t) flag[i][j]=;
}
}
int main(){
scanf("%d%d",&n,&m);
int cur=,x,y;
sum=n*m;
for (int i = ;i <= n;i ++) {
scanf("%s",s[i]);
for (int j=;j<m;j++)map[i][j+]=s[i][j]=='X'?:;
}
for (int i=;i<=n&&cur;i++) {
for (int j=;j<=m&&cur;j++) if (map[i][j]) {
if (flag[i][j]==-) cur=;
flag[i][j]=-;
for (int k=;k<;k++) {
x=i+go[k][],y=j+go[k][];
if (x<||x>n||y<||y>m) continue;
flag[x][y]=-;
}
}
}
if (!flag) {
printf("0\n");
return ;
}
ans=solve();
for (int i=;i<=n;i++)
for (int j=;j<=m;j++) if (flag[i][j]==) ie(i,j,);
(ans+=d39)%=d39;
printf("%d\n",ans);
return ;
}
bzoj 2669 状压DP的更多相关文章
- bzoj 1879 状压dp
879: [Sdoi2009]Bill的挑战 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 852 Solved: 435[Submit][Status ...
- bzoj 1087 状压dp
1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 4130 Solved: 2390[Submit][ ...
- BZOJ 2064 - 状压DP
传送门 题目大意: 给两个数组, 数组中的两个元素可以合并成两元素之和,每个元素都可以分裂成相应的大小,问从数组1变化到数组2至少需要多少步? 题目分析: 看到数据范围\(n<=10\), 显然 ...
- BZOJ 4057 状压DP
思路: 状压一下 就完了... f[i]表示选了的集合为i 转移的时候判一判就好了.. //By SiriusRen #include <cstdio> #include <cstr ...
- BZOJ 4565 状压DP
思路: f[i][j][S]表示从i到j压成S状态 j-m是k-1的倍数 $f[i][j][S<<1]=max(f[i][j][S<<1],f[i][m-1][S]+f[m][ ...
- bzoj 1072状压DP
1072: [SCOI2007]排列perm Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 2293 Solved: 1448[Submit][St ...
- bzoj 1072 状压DP
我们用w[i][j]来表示,i是一个二进制表示我们选取了s中的某些位,j表示这些位%d为j,w[i][j]则表示这样情况下的方案数,那么我们可以得到转移.w[i|(1<<k)][(j*10 ...
- bzoj 1076 状压DP
我们设w[i][s]为当前到第i关,手中的物品为s的时候,期望得分为多少,其中s为二进制表示每种物品是否存在. 那么就比较容易转移了w[i][s]=(w[i-1][s']+v[j]) *(1/k),其 ...
- BZOJ 1231 状压DP
思路: f[i][j] i表示集合的组成 j表示选最后一个数 f[i][j]表示能选的方案数 f[i|(1<< k)][k]+=f[i][j]; k不属于i j属于i且符合题意 最后Σf[ ...
随机推荐
- win7 安装 MongoDB 及简单操作
下载地址 http://dl.mongodb.org/dl/win32/x86_64 这里用的版本是 mongodb-latest-signed.msi 同时下载 mongodb-compass 下载 ...
- 特殊符号存入mysql数据库时报错:Incorrect string value: '\xF0\x9F\x98\x84\xF0\x9F的解决方法
问题描述:从新浪微博抓取消息保存到MySQL数据中,对应数据库字段为varchar,字符编码utf-8.部分插入成功,部分插入失败,报错如标题. 在网上查询,有人说是编码问题,建议修改编码格式,比如改 ...
- hdu5575 Discover Water Tank
题意: 给出个水箱,水箱两侧有无限高的隔板,水箱内有整数高度的隔板将水箱分成n-1份,现在给出m个限制,每个限制表示某个位置的某个高度有水或没水,问最多能同时满足多少个限制.n,m<=2*10^ ...
- Django Models相关
Models的相关知识 1. AutoField:自增整数类型.根据 ID 自增长的 Int字段 2. IntegerField:整数类型 3. BigIntegerField:大整数类型.用于数值较 ...
- 安装单机Hadoop系统(完整版)——Mac
在这个阴雨绵绵的下午,没有睡午觉的我带着一双惺忪的眼睛坐在了电脑前,泡上清茶,摸摸已是略显油光的额头(笑cry),,奋斗啊啊啊啊!!%>_<% 1.课程回顾. 1.1 Hadoop系统运行 ...
- Tensorflow框架初尝试————搭建卷积神经网络做MNIST问题
Tensorflow是一个非常好用的deep learning框架 学完了cs231n,大概就可以写一个CNN做一下MNIST了 tensorflow具体原理可以参见它的官方文档 然后CNN的原理可以 ...
- python中深copy,浅copy
版权声明:本文为博主原创文章,未经博主允许不得转载. >>> mylist1 = [1, 2, 3, 4] >>> myl = mylist1 >>&g ...
- JS详细图解全方位解读this
JS详细图解全方位解读this 对于this指向的理解中,有这样一种说法:谁调用它,this就指向谁.在我刚开始学习this的时候,我是非常相信这句话的.因为在一些情况下,这样理解也还算说得通.可是我 ...
- 周记【距gdoi:133天】
蔡大神坚持每天写日记记录他所剩的oi生涯. 可是我呢?自从搞完数据结构后都不知道在干什么,整天在傻叉.也许是给自己压力太大了,或许是真的自己在迷茫以及犹豫,更或者自己真的是想太多不想写题,觉得烦了,没 ...
- BZOJ1591 & 洛谷2924:[USACO2008 DEC]Largest Fence 最大的围栏——题解
http://www.lydsy.com/JudgeOnline/problem.php?id=1591 https://www.luogu.org/problemnew/show/P2924#sub ...