题目链接

P3160 [CQOI2012]局部极小值

双倍经验,双倍快乐

解题思路

存下来每个坑(极小值点)的位置,以这个序号进行状态压缩。

显然,\(4*7\)的数据范围让极小值点在8个以内(以下示意)

X . X . X . X .

. . . . . . . .

X . X . X . X .

. . . . . . . .

所以考虑用\(S\)表示各个极小值点是否已填的状态,枚举\(1-n*m\)进行状压\(DP\)。

当前填的数有两种选择:

(\(1\))填入坑中,这样枚举\(S\)状态表示的每一个已填的坑,\(f[i][S]+=\)\(\sum_{k|((1<<k)\&S==0)}^{} {f[i-1][S-(1<<k)]}\)(\(k\)表示第\(k\)个坑是没填过的)(这步的意思是:\(S-(1<<k)\)这个状态没有填\(k\)位置的坑,我现在\(i\)要填这个坑的种类数就是\(f[i-1][S-(1<<k)]\))

(\(2\))不填入坑中,这样枚举每一个点,如果可以填(指如果有坑还没填,那么他旁边以及他本身共\(9\)个格都不能填东西,否则这个坑继续往后填填不成极小值),那么就是一种新的填法,数出来\(tot\)种填法,那么\(dp[i][S]+=dp[i-1][S]*(tot-i+1)\)。然后发现枚举不是很好,可以进行预处理,处理出每一个状态对应的\(tot\)(代码中用\(hi[S]\)表示)。

然后答案就是\(f[m*n][(1<<num)-1]\)。(\(num\)代表坑的个数)

然后因为是胡乱填数,于是可能会出现不应该是坑的地方变成坑的情况,于是就在每个可能出现坑的地方分别新加一个坑进行\(DP\),完了再减去。而这个\(DP\)又带来新的可能填的坑......而这就是个容斥问题了。

AC代码

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
char a[10];
int m,n,min[6][10];//描述整个矩阵
int num,x[30],y[30];//描述坑的个数、位置
int w=12345678;//膜
int dx[10]={-1,-1,-1,0,0,1,1,1,0};//移动位置
int dy[10]={-1,0,1,-1,1,-1,0,1,0};
int vis[6][10],f[29][(1<<8)+10],hi[1<<9];//dp用到的东西
int dp(){
int i,j,k;
memset(f,0,sizeof(f));
f[0][0]=1;
for(i=0;i<(1<<num);i++){//预处理出每个状态i对应的可填点数量
hi[i]=n*m;
memset(vis,0,sizeof(vis));
for(j=0;j<num;j++)if(!(i&(1<<j)))for(k=0;k<9;k++)vis[x[j]+dx[k]][y[j]+dy[k]]=1;
for(j=1;j<=n;j++)for(k=1;k<=m;k++)if(vis[j][k])hi[i]--;
}
for(i=1;i<=n*m;i++){//枚举填哪个数
for(j=0;j<(1<<num);j++){//枚举状态
if(hi[j]-i+1>0)f[i][j]+=f[i-1][j]*(hi[j]-i+1),f[i][j]%=w;
for(k=0;k<num;k++)if((1<<k)&j)f[i][j]+=f[i-1][j^(1<<k)],f[i][j]%=w;
}
}
return f[n*m][(1<<num)-1];
}
int dfs(int X,int Y){
if(Y==m+1)X++,Y=1;
if(X==n+1)return dp();
int i,ans=dfs(X,Y+1);
for(i=0;i<9;i++)if(min[X+dx[i]][Y+dy[i]])return ans;
//如果没return说明这个地方是个可能变成坑的地方,那就把它变成坑dfs一下
x[num]=X;y[num++]=Y;min[X][Y]=1;
ans-=dfs(X,Y+1),ans=(ans+w)%w;
min[X][Y]=0;num--;//别忘了变回去
return ans;
}
int main(){
int i,j;
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
scanf("%s",a+1);
for(j=1;j<=m;j++)if(a[j]=='X'){
min[i][j]=1;
x[num]=i;y[num++]=j;
}
}
for(i=0;i<num;i++)for(j=0;j<i;j++)if(abs(x[i]-x[j])<2&&abs(y[i]-y[j])<2)return printf("0"),0;
if(!num)return printf("0"),0;
printf("%d",dfs(1,1));
return 0;
}

P3160 [CQOI2012]局部极小值 题解(状压DP+容斥)的更多相关文章

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

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

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

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

  3. 【BZOJ 2669】 2669: [cqoi2012]局部极小值 (状压DP+容斥原理)

    2669: [cqoi2012]局部极小值 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 667  Solved: 350 Description 有一 ...

  4. codeforces 342D Xenia and Dominoes(状压dp+容斥)

    转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud D. Xenia and Dominoes Xenia likes puzzles ...

  5. 一本通 1783 矩阵填数 状压dp 容斥 计数

    LINK:矩阵填数 刚看到题目的时候感觉是无从下手的. 可以看到有n<=2的点 两个矩形. 如果只有一个矩形 矩形外的方案数容易计算考虑 矩形内的 必须要存在x这个最大值 且所有值<=x. ...

  6. HDU 5838 (状压DP+容斥)

    Problem Mountain 题目大意 给定一张n*m的地图,由 . 和 X 组成.要求给每个点一个1~n*m的数字(每个点不同),使得编号为X的点小于其周围的点,编号为.的点至少大于一个其周围的 ...

  7. [清华集训2015 Day1]主旋律-[状压dp+容斥]

    Description Solution f[i]表示状态i所代表的点构成的强连通图方案数. g[i]表示状态i所代表的的点形成奇数个强连通图的方案数-偶数个强连通图的方案数. g是用来容斥的. 先用 ...

  8. NOIp模拟赛 巨神兵(状压DP 容斥)

    \(Description\) 给定\(n\)个点\(m\)条边的有向图,求有多少个边集的子集,构成的图没有环. \(n\leq17\). \(Solution\) 问题也等价于,用不同的边集构造DA ...

  9. uoj#37. 【清华集训2014】主旋律(状压dp+容斥)

    传送门 第一眼容斥,然后我就死活容不出来了-- 记\(f_i\)为点集\(i\)中的点强联通的方案数,那么就是总的方案数减去使\(i\)不连通的方案数 如果\(i\)不连通的话,我们可以枚举缩点之后拓 ...

随机推荐

  1. Kubernets二进制安装(9)之部署主控节点控制器controller-manager

    kube-controller-manager运行控制器,它们是处理集群中常规任务的后台线程 Controller Manager就是集群内部的管理控制中心,由负责不同资源的多个Controller构 ...

  2. 一些CTF题目--20/9/3

    1. 看源码 POST方法.Extract覆盖. 直接url ?参数不行,因为POST参数不在URL上,GET参数才在 Burpsuite抓包,改成  pass=1&thepassword_1 ...

  3. leetcode8 字符串转换整数

    <cctype> isdigit(char) 问题:在做乘法,加法前,先判断是否溢出 &&优先级大于== 然后教训: 考虑情况不周.比如3.14这样 然后解决办法 多自己搞 ...

  4. spring-cloud-netflix-hystrix-dashboard

    Hystrix-dashboard是一款针对Hystrix进行实时监控的工具,通过Hystrix Dashboard我们可以在直观地看到各Hystrix Command的请求响应时间, 请求成功率等数 ...

  5. 康托展开:对全排列的HASH和还原,判断搜索中的某个排列是否出现过

    题目:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=2297 前置技能:(千万注意是 ...

  6. Linux 驱动框架---驱动中的异步

    异步IO是对阻塞和轮询IO的机制补充,所谓异步IO就是在设备数据就绪时主动通知所属进程进行处理的机制.之所以说是异步是相对与被通知进程的,因为进程不知道也无法知道什么时候会被通知:这一机制非常类似于硬 ...

  7. 你所不知道的 JS: null , undefined, NaN, true==1=="1",false==0=="",null== undefined

    1 1 1 === 全相等(全部相等) ==  值相等(部分相等) demo: var x=0; undefined var y=false; undefined if(x===y){ console ...

  8. prefetch & preload & prerender & dns-prefetch & preconnect

    prefetch & preload & prerender & dns-prefetch & preconnect performance optimization ...

  9. convert URL Query String to Object All In One

    convert URL Query String to Object All In One URL / query string / paramas query string to object le ...

  10. linux下安装mysql8.0.x步骤

    1.下载mysql mysql官网:https://dev.mysql.com/downloads/mysql/ 将下载的mysql上传打linux 2.解压并重命名 [root@rsyncClien ...