UVa11725 - Colorful Board(BITMASK+DP)

5 篇文章 0 订阅

Colorful Board

Input: Standard Input

Output: Standard Output

 

You are given a board. You are asked to draw M horizontal lines and N vertical lines in that board, so that the whole board is divided into (M+1) x (N+1) cells. So there will be M + 1 rows each of which will exactly contain N + 1 cells.

 

Now you are asked to color every cell. For these purpose, you are given four colors.

            Red

            Green

            Blue

            Orange

 

To make the board more beautiful and colorful, you have to be careful, so that no two adjacent cells contain the same color. Two cells are considered adjacent if they share a common side.

 

You are also given some forbidden cells. You must not draw anything in those cells. But you must color every other cell which are not forbidden using a single color.

 

You have to answer in how many ways you can color this board.

 

Red

Green

Blue

Orange

 

Valid

Green

Orange

Orange

Green

 

Valid

Orange

Green

Orange

Blue

 

Invalid

 

Figure: Some examples of valid and invalid coloring, where M = 1, N = 1 and no forbidden cell.

 

 

Input

 

Input will start with an integer T(T<=50) which indicates the number of test case. Each case will start with two integers M and N (0<=M, N<=6), number of horizontal lines and number of vertical lines. Next line will contain an integer K ( 0<=K<=(M+1)*(N+1) ), which indicates the number of forbidden cells. Each of the next K lines will contain two integers x and y (1<=x<=M+1, 1<=y<=N+1), representing one forbidden cell, which is yth cell of xth row. Each given forbidden cells are distinct.

 

Output

 

For each test case, output a single line in the form “Case #: P”, where # will be replaced by the case number and P will be replaced by the number of valid ways you can draw the given board. The result can be very large you should output the result modulo 1000000007.

Sample Input                             Output for Sample Input

2

1 1

1

2 1

0 0

0

 

Case 1: 36

Case 2: 4

 



#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
ll dp[7][16384];
ll no[7][7];
const int MOD = 1000000007;
int fmask;
int n,m;
void init(){
    memset(dp,0,sizeof dp);
    memset(no,0,sizeof no);
    fmask = 1<<(2*m);
}
void dfs(int row,int col,int lastmask,int nowmask,int val){
    if(col==m){
        dp[row][nowmask] = (dp[row][nowmask]+val)%MOD;
        return;
    }
    if(no[row][col])   dfs(row,col+1,lastmask,nowmask,val);
    else{
          int up = (lastmask >>col*2)&3,left = (nowmask>>(col-1)*2)&3;
          for(int i = 0; i < 4; i++){
                if((col==0||no[row][col-1]||i!=left)&&(row==0||no[row-1][col]||i!=up)){
                    nowmask |= i<<(col*2);
                    dfs(row,col+1,lastmask,nowmask,val);
                    nowmask ^= i<<(col*2);
                }
          }
    }

}
int main(){
    int ncase,T=1,k;
   // freopen("in","r",stdin);
    cin >> ncase;
    while(ncase--){
        cin >> n >> m >> k;
        m++;
        n++;
        init();
        while(k--){
            int a,b;
            cin >> a >> b;
            a--;b--;
            no[a][b] =  1;
        }
        dfs(0,0,0,0,1);
        for(int i = 1; i < n; i++){
            for(int j = 0; j < fmask; j++){
                if(dp[i-1][j]){
                    dfs(i,0,j,0,dp[i-1][j]);
                }
            }
        }
        ll ans = 0;
        for(int i = 0; i < fmask; i++)
            ans = (ans+dp[n-1][i])%MOD;

        printf("Case %d: %lld\n",T++,ans);


    }
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值