BUPT Summer Journey #test9 D

来源:互联网 发布:python命令行参数解析 编辑:程序博客网 时间:2024/05/27 09:45

 

D. 学妹去搬砖 2014新生暑假个人排位赛09

时间限制 1000 ms    内存限制 65536 KB    

题目描述

大家都知道,学校里有很多路在修,修路需要砖块。这一天,Mr.F来到集训队,找学妹去帮忙搬砖块。善良的学长们不忍心让学妹劳动,就争先恐后的帮助学妹搬砖。于是聪明的学妹说,我出一个题,谁答出来谁就能帮我搬砖。
把学校要铺的地面看成是n*m的方格,每一块砖的大小是1*2,学妹想知道有多少种方法可以把这块地铺满。注意地上有可能会有花花草草,有爱心的学妹不忍心砖块把它们压死,所以这些点是不可以铺砖块的。

输入格式

输入多组数据,数据组数不超过20组。每组第一行为三个整数n, m, k,(1<=n, m<=10),k<=n*m,分别代表地面的长宽,以及花花草草的数量。接下来k行,每行一组x,y,表示花花草草的坐标。详细方向见样例。

输出格式

每组输出一个数,即最后的方案数。由于输出会很大,请输出答案mod 1000000007(10^9+7)。

输入样例

3 1 12 03 1 0

输出样例

10hint:第一组样例所示地面为:..*其中‘.‘表示空地,’*‘表示花花草草,一种方案可以铺满。

 

思路:一个轮廓线DP,也可以定点划分成二分图最大匹配来解决。

代码:

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#define maxn 15#define MOD 1000000007//#define LOCALusing namespace std;int n,m,k;int color[maxn][maxn];int dp[2][1<<maxn];void Solve(){    int *crt=dp[0],*next=dp[1];    crt[0]=1;    for(int i=n-1;i>=0;i--)    {        for(int j=m-1;j>=0;j--)        {            for(int used=0;used<1<<m;used++)            {                if(used>>j&1||color[i][j])next[used]=crt[used&~(1<<j)];                else                {                    int res=0;                    if(j+1<m&&!(used>>(j+1)&1)&&!color[i][j+1])res+=crt[used|1<<(j+1)];                    if(i+1<n&&!color[i+1][j])res+=crt[used|1<<j];                    next[used]=res%MOD;                }            }            swap(crt,next);        }    }    printf("%d\n",crt[0]);}int main(){    #ifdef LOCAL    freopen("input.txt","r",stdin);    #endif // LOCAL    while(scanf("%d%d%d",&n,&m,&k)==3)    {        int x,y;        memset(color,0,sizeof(color));        memset(dp,0,sizeof(dp));        for(int i=1;i<=k;i++)        {            scanf("%d%d",&x,&y);            color[x][y]=1;        }        //for(int i=0;i<n;i++){for(int j=0;j<m;j++)printf("%d",color[i][j]);printf("\n");}        //printf("\n");        Solve();    }    return 0;}


 

0 0
原创粉丝点击