P3160 [CQOI2012]局部极小值(dfs+状压dp)
时间:2019-08-19
本文章向大家介绍P3160 [CQOI2012]局部极小值(dfs+状压dp),主要包括P3160 [CQOI2012]局部极小值(dfs+状压dp)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
题目描述
有一个n行m列的整数矩阵,其中1到nm之间的每个整数恰好出现一次。如果一个格子比所有相邻格子(相邻是指有公共边或公共顶点)都小,我们说这个格子是局部极小值。给出所有局部极小值的位置,你的任务是判断有多少个可能的矩阵。
输入格式
输入第一行包含两个整数n和m(1<=n<=4, 1<=m<=7),即行数和列数。以下n行每行m个字符,其中”X“表示局部极小值,”.“表示非局部极小值。
输出格式
输出仅一行,为可能的矩阵总数除以12345678的余数。
输入输出样例
输入 #1
3 2
X.
..
.X
输出 #1
60
SOLUTION:
见洛谷
CODE:
#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 cnt=0; int P=0; int dfs(int X,int Y){ if(Y==m+1)X++,Y=1; if(X==n+1) { if(cnt%2==1)P-=dp();else P+=dp(); P%=w;P+=w;P%=w; return 0; } dfs(X,Y+1); int i; for(i=0;i<9;i++)if(min[X+dx[i]][Y+dy[i]])return 1; //如果没return说明这个地方是个可能变成坑的地方,那就把它变成坑dfs一下 x[num]=X;y[num++]=Y; min[X][Y]=1; cnt++; dfs(X,Y+1); min[X][Y]=0;num--;//别忘了变回去 cnt--; return 1; } 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; dfs(1,1); printf("%d",P); return 0; }
原文地址:https://www.cnblogs.com/zhangbuang/p/11375415.html
- CSS魔法堂:深入理解line-height和vertical-align
- Gradle 10分钟上手指南
- gradle项目中profile的实现
- 欧盟推出“数字经济税收制度”优化了税收制度,却影响区块链行业
- CSS魔法堂:你一定误解过的Normal flow
- ASP.NET输出JSON格式数据
- haproxy 新手上路
- 区块链是如何保护交易隐私的?eprint这篇论文告诉你答案
- gradle项目中资源文件的相对路径打包处理技巧
- Markdown 语法手册 (完整整理版)
- WordPress3.5安装出现的几个问题
- java并发编程学习: 原子变量(CAS)
- gradle项目中如何支持java与scala混合使用?
- 开始使用Linux
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 【Flutter组件终结篇】332个组件 658页PDF
- Kubernetes在pod中配置hosts解析域名
- 【Flutter 实战】简约而不简单的计算器
- Flutter 中渐变的高级用法
- 【Flutter实战】动画核心(1/2)
- 【Flutter实战】动画核心(2/2)
- Flutter 1.17 新 Material motion 规范的预构建动画
- Canonical通过Flutter启用Linux桌面应用程序支持
- Flutter 快捷开发 Mac Android Studio 篇
- TRTC Android端开发接入学习之互动直播(七)
- Flutter 实现酷炫的3D效果
- 【Flutter 实战】一文学会20多个动画组件
- 【Flutter 实战】动画序列、共享动画、路由动画
- 【Flutter 实战】自定义动画-涟漪和雷达扫描
- Flutter —布局系统概述