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

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud

D. Xenia and Dominoes

Xenia likes puzzles very much. She is especially fond of the puzzles that consist of domino pieces. Look at the picture that shows one of such puzzles.

A puzzle is a 3 × n table with forbidden cells (black squares) containing dominoes (colored rectangles on the picture). A puzzle is calledcorrect if it meets the following conditions:

  • each domino occupies exactly two non-forbidden cells of the table;
  • no two dominoes occupy the same table cell;
  • exactly one non-forbidden cell of the table is unoccupied by any domino (it is marked by a circle in the picture).

To solve the puzzle, you need multiple steps to transport an empty cell from the starting position to some specified position. A move is transporting a domino to the empty cell, provided that the puzzle stays correct. The horizontal dominoes can be moved only horizontally, and vertical dominoes can be moved only vertically. You can‘t rotate dominoes. The picture shows a probable move.

Xenia has a 3 × n table with forbidden cells and a cell marked with a circle. Also, Xenia has very many identical dominoes. Now Xenia is wondering, how many distinct correct puzzles she can make if she puts dominoes on the existing table. Also, Xenia wants the circle-marked cell to be empty in the resulting puzzle. The puzzle must contain at least one move.

Help Xenia, count the described number of puzzles. As the described number can be rather large, print the remainder after dividing it by1000000007 (109 + 7).

Input

The first line contains integer n (3 ≤ n ≤ 104) — the puzzle‘s size. Each of the following three lines contains n characters — the description of the table. The j-th character of the i-th line equals "X" if the corresponding cell is forbidden; it equals ".", if the corresponding cell is non-forbidden and "O", if the corresponding cell is marked with a circle.

It is guaranteed that exactly one cell in the table is marked with a circle. It is guaranteed that all cells of a given table having at least one common point with the marked cell is non-forbidden.

Output

Print a single number — the answer to the problem modulo 1000000007 (109 + 7).

Sample test(s)

input

5....X.O......X.

output

1

input

5......O........

output

2

input

3........O

output

4

Note

Two puzzles are considered distinct if there is a pair of cells that contain one domino in one puzzle and do not contain it in the other one.

好题。

问有几种排法使得有至少一块多米诺骨牌可以移动。其中O点和X点不能放置多米诺骨牌,但要求最终的可以通过O点移动。X点表示障碍。

要求的即为四个方向中至少有一个方向可以移动,所以,容斥的时候,把那个用X表示好,然后类似poj的铺砖问题,状压。

  1 //#####################
  2 //Author:fraud
  3 //Blog: http://www.cnblogs.com/fraud/
  4 //#####################
  5 #include <iostream>
  6 #include <sstream>
  7 #include <ios>
  8 #include <iomanip>
  9 #include <functional>
 10 #include <algorithm>
 11 #include <vector>
 12 #include <string>
 13 #include <list>
 14 #include <queue>
 15 #include <deque>
 16 #include <stack>
 17 #include <set>
 18 #include <map>
 19 #include <cstdio>
 20 #include <cstdlib>
 21 #include <cmath>
 22 #include <cstring>
 23 #include <climits>
 24 #include <cctype>
 25 using namespace std;
 26 #define XINF INT_MAX
 27 #define INF 0x3FFFFFFF
 28 #define MP(X,Y) make_pair(X,Y)
 29 #define PB(X) push_back(X)
 30 #define REP(X,N) for(int X=0;X<N;X++)
 31 #define REP2(X,L,R) for(int X=L;X<=R;X++)
 32 #define DEP(X,R,L) for(int X=R;X>=L;X--)
 33 #define CLR(A,X) memset(A,X,sizeof(A))
 34 #define IT iterator
 35 typedef long long ll;
 36 typedef pair<int,int> PII;
 37 typedef vector<PII> VII;
 38 typedef vector<int> VI;
 39 #define MAXN 100010
 40 char a[5][MAXN];
 41 int dp[MAXN][10];
 42 int m[MAXN];
 43 const int MOD=1000000007;
 44 int n;
 45 int gao(){
 46     CLR(m,0);
 47     for(int i=0;i<3;i++){
 48         for(int j=0;j<n;j++){
 49             if(a[i][j]==‘X‘)m[j]|=1<<i;
 50         }
 51     }
 52     CLR(dp,0);
 53     dp[0][0]=1;
 54     for(int i=0;i<n;i++){
 55         for(int j=0;j<8;j++){
 56             for(int k=0;k<8;k++){
 57                 if(k&m[i])continue;
 58                 int x=j|m[i]|k;
 59                 if((j&(k|m[i]))==0&&(x==7||x==4||x==1)){
 60                     dp[i+1][k]+=dp[i][j];
 61                     if(dp[i+1][k]>=MOD)dp[i+1][k]-=MOD;
 62                 }
 63             }
 64         }
 65     }
 66     return dp[n][0];
 67 }
 68 bool check(int x,int y){
 69     if(x>=0&&x<3&&y>=0&&y<n&&a[x][y]==‘.‘)return 0;
 70     return 1;
 71 }
 72 int dx[4]={-1,0,0,1};
 73 int dy[4]={0,1,-1,0};
 74 int main()
 75 {
 76     ios::sync_with_stdio(false);
 77     int ci,cj;
 78     int x[110],y[110],tot=0;
 79     cin>>n;
 80     for(int i=0;i<3;i++){
 81         for(int j=0;j<n;j++){
 82             cin>>a[i][j];
 83             if(a[i][j]==‘O‘)ci=i,cj=j,a[i][j]=‘X‘;
 84         }
 85     }
 86     int ans=0;
 87     for(int i=1;i<16;i++){
 88         int t=i;
 89         tot=0;
 90         int c=0;
 91         for(int j=0;j<4;j++){
 92             if(t&1){
 93                 x[tot]=dx[j];
 94                 y[tot++]=dy[j];
 95                 x[tot]=dx[j]*2;
 96                 y[tot++]=dy[j]*2;
 97                 c++;
 98             }
 99             t>>=1;
100         }
101         bool flag=1;
102         for(int j=0;j<tot;j++){
103             if(check(ci+x[j],cj+y[j]))flag=0;
104         }
105         if(flag){
106             for(int j=0;j<tot;j++){
107                 a[ci+x[j]][cj+y[j]]=‘X‘;
108             }
109             if(c&1)ans+=gao();
110             else ans-=gao();
111             if(ans>=MOD)ans-=MOD;
112             else if(ans<0)ans+=MOD;
113             for(int j=0;j<tot;j++){
114                 a[ci+x[j]][cj+y[j]]=‘.‘;
115             }
116         }
117     }
118     cout<<ans<<endl;
119
120
121     return 0;
122 }

代码君

时间: 2024-11-03 21:30:10

codeforces 342D Xenia and Dominoes(状压dp+容斥)的相关文章

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

题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=2669 题解 可以发现一个 \(4\times 7\) 的矩阵中,有局部最小值的点最多有 \(2\times 4 = 8\) 个,所以我们可以状压一下每个局部最小值的位置有没有被选. 从小到大填入每一个格子,那么如果一个点的周围有没有被填上的局部最小值,那么这个格子不可以被填.所以预处理一下每种状态下可以自由填多少格子,然后如果状态保持不变的话,就可以这样转移. 如果状态变化,就是说填了一个局

HDU 5838 (状压DP+容斥)

Problem Mountain 题目大意 给定一张n*m的地图,由 . 和 X 组成.要求给每个点一个1~n*m的数字(每个点不同),使得编号为X的点小于其周围的点,编号为.的点至少大于一个其周围的点.   n<=5 , m<=5. 解题分析 考虑从1~n*m,从小到大依次填数,则如果某个位置编号为X且该位置还未填数,那么其周围的点均不能填数. 令dp[i][j]表示填到第i个数,状态为j . 令X的个数为cnt,那么 j ∈[ 0 , 1<<cnt). 一种情况为第i个数填在

2016 CCPC 网络赛 B 高斯消元 C 树形dp(待补) G 状压dp+容斥(待补) H 计算几何

2016 CCPC 网络赛 A - A water problem 水题,但读题有个坑,输入数字长度很大.. B - Zhu and 772002 题意:给出n个数(给出的每个数的质因子最大不超过2000),选出多个数相乘得b.问有多少种选法让b 为完全平方数. tags:高斯消元,求异或方程组解的个数.   好题 每个数先素数分解开.  对于2000以内的每个素数p[i],这n个数有奇数个p[i]则系数为1,偶数个则系数为0,最后n个数的p[i]系数异或和都要为0才会使得最后的积为完全平方数.

bzoj2560串珠子 状压dp+容斥(?)

2560: 串珠子 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 515  Solved: 348[Submit][Status][Discuss] Description 铭铭有n个十分漂亮的珠子和若干根颜色不同的绳子.现在铭铭想用绳子把所有的珠子连接成一个整体. 现在已知所有珠子互不相同,用整数1到n编号.对于第i个珠子和第j个珠子,可以选择不用绳子连接,或者在ci,j根不同颜色的绳子中选择一根将它们连接.如果把珠子看作点,把绳子看作边,将所

【BZOJ2560】串珠子 状压DP+容斥

[BZOJ2560]串珠子 Description 铭铭有n个十分漂亮的珠子和若干根颜色不同的绳子.现在铭铭想用绳子把所有的珠子连接成一个整体. 现在已知所有珠子互不相同,用整数1到n编号.对于第i个珠子和第j个珠子,可以选择不用绳子连接,或者在ci,j根不同颜色的绳子中选择一根将它们连接.如果把珠子看作点,把绳子看作边,将所有珠子连成一个整体即为所有点构成一个连通图.特别地,珠子不能和自己连接. 铭铭希望知道总共有多少种不同的方案将所有珠子连成一个整体.由于答案可能很大,因此只需输出答案对10

CF449D Jzzhu and Numbers (状压DP+容斥)

题目大意: 给出一个长度为n的序列,构造出一个序列使得它们的位与和为0,求方案数 也就是从序列里面选出一个非空子集使这些数按位与起来为0. 看了好久才明白题解在干嘛,我们先要表示出两两组合位与和为0的所有情况 先hx一下每个数出现的次数,然后我们从遍历 i ,i 是二进制的数位 然后遍历所有的情况,如果第 i 位有1,那么说明我们去掉第 i 位的1就是又一种情况! 其实我们统计的是所有数在删掉/不删掉每一位的1 所有可能出现的数! 那么,状态内任意组合,不能取空集,总数就是 再根据容斥原理(最玄

Codeforces Gym 100676G Training Camp 状压dp

http://codeforces.com/gym/100676 题目大意是告诉你要修n门课,每门课有一个权值w[i], 在第k天修该课程讲获得k*w[i]的学习点数,给出了课程与先修课程的关系,要修该课程必须修完先修课程.问最多能学到多少点数. 非常简单的一道状压dp(一开始我还误导队友写成两维的去了 T^T); dp[s] : s 的二进制存放的是已经选择的课程,在该状态下的能获得的最大的点数. 这时如果再学一门课程k,将转移到状态ss (s | (1 << k) ) ,能否转移需要判断合

zoj zju 2994 Tiling a Grid With Dominoes 状压dp

Tiling a Grid With Dominoes Time Limit: 2 Seconds      Memory Limit: 65536 KB We wish to tile a grid 4 units high and N units long with rectangles (dominoes) 2 units by one unit (in either orientation). For example, the figure shows the five differen

Codeforces 11D - A Simple Task (状压DP)

题意 求出一个n个点m个边的图,求简单环有多少(没有重复点和边). 思路 这是个不错的题,这个状压dp保存的状态不是直接的环,而是路径的个数.s表示的状态为一条路径,则dp[s][i]表示以s的最小编号为起点,以i为终点的环的个数.那么我们就可以通过枚举状态,枚举状态中的起点和枚举路径外的终点,然后判断终点和起点是否相连来判断是否成环. 代码 #include <stdio.h> #include <string.h> #include <iostream> #incl