time limit per test

1.5 seconds

memory limit per test

512 megabytes

input

standard input

output

standard output

Polycarp owns a shop in the capital of Berland. Recently the criminal activity in the capital increased, so Polycarp is thinking about establishing some better security in the storehouse of his shop.

The storehouse can be represented as a matrix with n rows and m columns. Each element of the matrix is either . (an empty space) or x (a wall).

Polycarp wants to hire some guards (possibly zero) to watch for the storehouse. Each guard will be in some cell of matrix and will protect every cell to the right of his own cell and every cell to the bottom of his own cell, until the nearest wall. More formally, if the guard is standing in the cell (x0, y0), then he protects cell (x1, y1) if all these conditions are met:

  • (x1, y1) is an empty cell;
  • either x0 = x1 and y0 ≤ y1, or x0 ≤ x1 and y0 = y1;
  • there are no walls between cells (x0, y0) and (x1, y1). There can be a guard between these cells, guards can look through each other.

Guards can be placed only in empty cells (and can protect only empty cells). The plan of placing the guards is some set of cells where guards will be placed (of course, two plans are different if there exists at least one cell that is included in the first plan, but not included in the second plan, or vice versa). Polycarp calls a plan suitable if there is not more than one empty cell that is not protected.

Polycarp wants to know the number of suitable plans. Since it can be very large, you have to output it modulo 109 + 7.

Input

The first line contains two numbers n and m — the length and the width of the storehouse (1 ≤ n, m ≤ 250, 1 ≤ nm ≤ 250).

Then n lines follow, ith line contains a string consisting of m characters — ith row of the matrix representing the storehouse. Each character is either . or x.

Output

Output the number of suitable plans modulo 109 + 7.

Examples
Input
1 3
.x.
Output
3
Input
2 2
xx
xx
Output
1
Input
2 2
..
..
Output
10
Input
3 1
x
.
x
Output
2
Note

In the first example you have to put at least one guard, so there are three possible arrangements: one guard in the cell (1, 1), one guard in the cell (1, 3), and two guards in both these cells.

题意:

  在地图上放士兵守卫,  " . " 代表那个位置可以放士兵 , " x " 代表那个位置是墙

  士兵的守卫范围为:

    ① 士兵右侧连续的的 " . " 直到墙或者地图边缘
    ② 士兵下方连续的的 " . " 直到墙或者地图边缘
    ③ 士兵所处的位置

  求 放置士兵使得士兵守卫的不到的位置 <=1 的方案数 (不包括墙)

思路:

  由于  1 ≤ nm ≤ 250   所以始终  min ( n,m ) ≤ 15    这是个有用的信息

  容易发现 , 放完左上方位置的士兵后左上的情况不会受下面或者右边的影响

  因此可以考虑dp

  dp [ i ]  表示 按如图编号顺序 从上到下 从左往右 放置第 i 个士兵的局面

  

  状态有两种

    1)当前局面已经有一个位置守卫不到

    2)当前所有位置都能被守护

  但是我们发现一个问题 我们 怎样知道当前位置 放置/不放置 士兵会造成什么影响呢

  所以我们需要知道 两个东西

    1)上方是否有士兵能守卫到当前位置

    2)左侧是否有士兵能守卫到当前位置

  这时候对第一点  考虑到状压dp  ( 因为min(n,m)<=15  ) 2进制的当前位为 1 则上方有士能守卫到这个位置   为 0 则没有

  对第二点考虑增加一维 表示 dp 的状态      1 代表左侧有士能守卫到这个位置    0 则没有

  所以 dp方程变成了 4 维  dp [ i ] [ j ] [ k ] [ h ]     表示

  放置第 i 个士兵   ,    j  代表2进制表示上方的状态   ,    k 代表 是否左侧有士兵能守卫当前位置 0为没有 1为有 ,  h表示已经被考虑过的位置有多少位置无法被守卫

  转移方式如下图

  

  紫色线的左侧和上方为被考虑过的位置 红色为当前位置 蓝色为放置完士兵

  那么 图中状态就是

  dp  [ i ] [ j ] [ k ] [ h ]

  i  =  9

  j  =  1110 (二进制) ///分别表示  第一列 第二列 第三列 第四列

  k = 0  ( 左侧无士兵 )

  h = 0 (没有被守卫到的位置为 0 个)

  如果当前位置放置士兵  转移到

  

  dp [ i ] [ j ]  [ k ] [ h ]

  i  =  10

  j  =  1110 (二进制) ///分别表示  第一列 第二列 第三列 第四列

  k = 1  ( 左侧有士兵 )

  h = 0 (没有被守卫到的位置为 0 个)

  否则转移到

  dp [ i ] [ j ]  [ k ] [ h ]

  i  =  10

  j  =  1110 (二进制) ///分别表示  第一列 第二列 第三列 第四列

  k = 0  ( 左侧无士兵 )

  h = 0 (没有被守卫到的位置为 0 个)

  注意到两点

   ① 放行末的士兵时 由于要转移到下一行的第一个  那么 他转移时所有状态中的(  dp[ i ] [ j ] [ k ] [h ]  )  k 只能是 0 
   ② 由于 min (n , m ) <=15  所以当列数比较多时要把 地图行列翻转  使得列数<=15

  具体的转移情况稍微看一下就出来了 代码中也有

  为了节省空间 转移时可以用滚动数组把dp的第一维降下来

  代码:

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
#include <functional> #define mp make_pair
#define pb push_back
#define mes(a,b) memset(a,b,sizeof(a))
#define mes0(a) memset(a,0,sizeof(a))
#define lson l,mid,pos<<1
#define rson mid+1,r,pos<<1|1
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define fi first
#define se second
#define sss(a) a::iterator
#define all(a) a.begin(),a.end() using namespace std; typedef double DB;
typedef long long LL;
typedef pair<int,int> pii;
typedef pair<long long ,int> pli;
typedef pair<int,long long > pil;
typedef pair<string,int> psi;
typedef pair<long long ,long long > pll; const int inf = 0x3f3f3f3f;
const long long INF = 0x3f3f3f3f3f3f3f3f;
const double pi = acos(-1.0);
const int maxn = +;
const int mod = 1e9+;
char MAP[][];
int n,m;
int dp[][(<<)][][]; /// 滚动 , 状压 , 左侧状态, 已填完的是否有空
int main()
{
dp[][][][]=;
int op=; ///滚动
scanf("%d%d",&n,&m);
if (m<=n){
for (int i=;i<n;i++){
scanf("%s",MAP[i]);
}
}else {
for (int i=;i<n;i++){
getchar();
for (int j=;j<m;j++){
MAP[j][i]=getchar();
}
}
swap(n,m);
}
for (int i=;i<n;i++){
int j;
for (j=;j<m;j++){
int flag=(j!=m-);
int now=m-j-;
int k;
memset(dp[op^],,sizeof(dp[op^]));
if (MAP[i][j]=='.'){
for (k=;k<(<<m);k++){
///dp[op][k][w][h];
/// m 1/0 是否填进去
/// 滚动数组, 状压 , 左侧状态, 已填完的是否有空
for (int m=;m<;m++){
for (int w=;w<;w++){
int st=(k>>now)&;
int S=k|((m|st)<<now);
st=(m|w|st)^;
for (int h=;h<;h++){
dp[op^][S][(w|m)&flag][h+st]+=dp[op][k][w][h];
dp[op^][S][(w|m)&flag][h+st]%=mod;
}
}
}
}
op^=;
} else {
for (k=;k<(<<m);k++){
///dp[op][k][w][h];
/// m 1/0 是否填进去
/// 滚动数组 , 状压 , 左侧状态, 已填完的是否有空
for (int w=;w<;w++){
int st=(k>>now)&;
int S=(k^(st<<now));
for (int h=;h<;h++){
dp[op^][S][][h]+=dp[op][k][w][h];
dp[op^][S][][h]%=mod;
}
}
}
op^=;
}
}
}
int ans=;
for (int i=;i<(<<m);i++){
for (int j=;j<;j++){
ans+=dp[op][i][][j];
ans%=mod;
}
}
cout<<ans<<endl;
return ;
}

Educational Codeforces Round 27 F. Guards In The Storehouse的更多相关文章

  1. Educational Codeforces Round 40 F. Runner's Problem

    Educational Codeforces Round 40 F. Runner's Problem 题意: 给一个$ 3 * m \(的矩阵,问从\)(2,1)$ 出发 走到 \((2,m)\) ...

  2. Educational Codeforces Round 27 补题

    题目链接:http://codeforces.com/contest/845 A. Chess Tourney 水题,排序之后判断第n个元素和n+1个元素是不是想等就可以了. #include < ...

  3. Educational Codeforces Round 61 F 思维 + 区间dp

    https://codeforces.com/contest/1132/problem/F 思维 + 区间dp 题意 给一个长度为n的字符串(<=500),每次选择消去字符,连续相同的字符可以同 ...

  4. Educational Codeforces Round 51 F. The Shortest Statement(lca+最短路)

    https://codeforces.com/contest/1051/problem/F 题意 给一个带权联通无向图,n个点,m条边,q个询问,询问两点之间的最短路 其中 m-n<=20,1& ...

  5. Educational Codeforces Round 12 F. Four Divisors 求小于x的素数个数(待解决)

    F. Four Divisors 题目连接: http://www.codeforces.com/contest/665/problem/F Description If an integer a i ...

  6. Educational Codeforces Round 26 F. Prefix Sums 二分,组合数

    题目链接:http://codeforces.com/contest/837/problem/F 题意:如题QAQ 解法:参考题解博客:http://www.cnblogs.com/FxxL/p/72 ...

  7. Educational Codeforces Round 9 F. Magic Matrix 最小生成树

    F. Magic Matrix 题目连接: http://www.codeforces.com/contest/632/problem/F Description You're given a mat ...

  8. Educational Codeforces Round 6 F. Xors on Segments 暴力

    F. Xors on Segments 题目连接: http://www.codeforces.com/contest/620/problem/F Description You are given ...

  9. Educational Codeforces Round 7 F. The Sum of the k-th Powers 拉格朗日插值法

    F. The Sum of the k-th Powers 题目连接: http://www.codeforces.com/contest/622/problem/F Description Ther ...

随机推荐

  1. [CF617E]XOR and Favorite Number/[CQOI2018]异或序列

    题目大意: 给定一个长度为$n(n\leq10^5)$的数列$A$和数$k$$(A_i,k\leq10^6)$.$m$组询问,每次询问区间$[l,r]$中有多少对$i,j(l\leq i\leq j\ ...

  2. mysql----kill慢查询

    每个与mysqld的连接都在一个独立的线程里运行,您可以使用SHOW PROCESSLIST语句查看哪些线程正在运行,并使用KILL thread_id语句终止一个线程. 如果您拥有SUPER权限,您 ...

  3. (转)Unity3D协同程序(Coroutine)

    一.什么是协同程序 协同程序,即在主程序运行时同时开启另一段逻辑处理,来协同当前程序的执行.换句话说,开启协同程序就是开启一个线程. 二.协同程序的开启与终止 在Unity3D中,使用MonoBeha ...

  4. 【转】C++调用Matlab的.m文件

    原文地址     Matlab是一个强大的数学计算/仿真工 具,其内置了很多实用的现成的函数,而且我们经常也自己定义很多m函数.但在很多情况下,我们不得不使用VC编程.那么,如何在VC中利用matla ...

  5. Git:fatal: The remote end hung up unexpectedly

    一.配置公共密钥 https://help.github.com/articles/generating-ssh-keys/ 二.设置缓冲值(push文件较大时导致错误) \.git\config [ ...

  6. JAVA常见算法题(九)

    package com.xiaowu.demo; /** * * 一个数如果恰好等于它的因子之和,这个数就称为"完数".例如6=1+2+3.编程找出1000以内的所有完数. * * ...

  7. 可以使用foreach遍历循环的条件

    大话C#中能使用foreach的集合的实现 转自:http://www.cnblogs.com/tangzhengyue/p/3339936.html   大家都知道foreach的语法: forea ...

  8. 详细理解javascript中的强制类型转换

    将值从一种类型转换为另一种类型通常称为类型转换,这是显式的情况:隐式的情况称为强制类型转换,JavaScript 中的强制类型转换总是返回标量基本类型值,如字符串.数字和布尔值. 如何理解: 类型转换 ...

  9. AcpectJ注释方式配置AOP

    1.AspectJ的概念   @AspectJ类似于Java注解的普通Java类   Spring可以使用AspectJ来做切入点解析   AOP的运行时仍旧是纯的Spring AOP,对Aspect ...

  10. 不厚道一回->Omnifocus 2 for mac license

    rt, 发个Omnifocus 2 for mac license. 其实Omnifocus 2的价格已经还算亲民了..可惜手贱一下子就找到了,所以没买了..不敢独享,所以分享给需要的人..有能力还是 ...