sgu 131 状压DP

棋盘覆盖(二)

时间限制:1000 ms  |  内存限制:65535 KB

描述
The banquet hall of Computer Scientists‘ Palace has a rectangular form of the size M x N (1<=M<=9, 1<=N<=9). It is necessary to lay hardwood floors in the hall. There are wood pieces of two forms:
1) rectangles (2x1) 
2) corners (squares 2x2 without one 1x1 square) 
You have to determine X - the number of ways to cover the banquet hall. 
Remarks. The number of pieces is large enough. It is not allowed to leave empty places, or to cover any part of a surface twice, or to saw pieces.
输入
The first line contains natural number M. The second line contains a natural number N.

输出
First line should contain the number X, or 0 if there are no solutions.
样例输入
2 3
样例输出
5

题意:有1*2的砖块和2*2但缺一个角的砖块,用他们恰好铺满m*n的矩形有几种方案。代码:
//思路就是:状压,从上到下铺dfs,sta表示本行的状态,next表示下一行的状态,每次要把sta铺满
//sta,next随之变化。最后要m+1行的状态为0才可以。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
ll dp[11][1<<10];
int n,m;
bool chak(int sta,int x){
    int tmp=(sta&(1<<x));
    return !tmp;
}
void dfs(int sta,int next,int col,int row,ll w){
    if(col==n){
        dp[row+1][next]+=w;
        return;
    }
    if(sta&(1<<col)) dfs(sta,next,col+1,row,w); //不放
    else{
        int st=(sta|(1<<col));
        if(chak(next,col)){
            dfs(sta|(1<<col),next|(1<<col),col+1,row,w);//竖着的1*2
            if(col+1<n&&chak(sta,col+1))
                dfs(st|(1<<(col+1)),next|(1<<col),col+1,row,w);//缺右上角的2*2
            st=(next|(1<<col));
            if(col+1<n&&chak(next,col+1))
                dfs(sta|(1<<col),st|(1<<(col+1)),col+1,row,w);//缺右下角的2*2
            if(col-1>=0&&chak(next,col-1))
                dfs(sta|(1<<col),st|(1<<(col-1)),col+1,row,w);//缺左下角的2*2
        }
        st=(sta|(1<<col));
        if(col+1<n&&chak(sta,col+1)){
            dfs(st|(1<<(col+1)),next,col+1,row,w);//横着的1*2
            if(chak(next,col+1))
                dfs(st|(1<<(col+1)),next|(1<<(col+1)),col+1,row,w);//缺左上角的2*2
        }
    }
}
int main()
{
    while(scanf("%d%d",&m,&n)==2){
        memset(dp,0,sizeof(dp));
        dp[1][0]=1;
        int N=(1<<n);
        for(int i=1;i<=m;i++){
            for(int j=0;j<N;j++){
                if(dp[i][j])
                    dfs(j,0,0,i,dp[i][j]);
            }
        }
        printf("%lld\n",dp[m+1][0]);
    }
    return 0;
}

时间: 2024-10-29 19:11:08

sgu 131 状压DP的相关文章

poj 2411 Mondriaan&#39;s Dream(状压DP)

Mondriaan's Dream Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 12232   Accepted: 7142 Description Squares and rectangles fascinated the famous Dutch painter Piet Mondriaan. One night, after producing the drawings in his 'toilet series

HDU 3001 Travelling 状压DP

链接:http://acm.hdu.edu.cn/showproblem.php?pid=3001 题意:还是环游地图的问题,只不过这回旅行者对自己有着严格的要求,地图上每个点的经过次数不能超过两次. 思路:依然是状压DP问题,根上一道很像,只不过这次对于每个点来说有三种状态,分别是未经过,经过一次,经过两次.所以要用三进制的数来进行状态压缩,这个关键点想明白了其他的和上一道基本一样了.对于我来说需要注意的是:能够到达某一个点经过了两次的状态的前一个状态是这个点已经经过了一次的状态,而不是从来未

NOJ 1116 哈罗哈的大披萨 【淡蓝】 [状压dp+各种优化]

我只能说,珍爱生命,远离卡常数的题...感谢陈老师和蔡神,没有他们,,,我调一个星期都弄不出来,,,, 哈罗哈的大披萨 [淡蓝] 时间限制(普通/Java) : 1000 MS/ 3000 MS          运行内存限制 : 65536 KByte总提交 : 73            测试通过 : 9 描述 热风哈罗哈(三牌楼)店正在搞活动:他们将提供一个大披萨给第一个告诉他们以下信息的人:一次购买任一种披萨,哪种单位面积的价格最低.问题初步想一想,好像是这么解决:“对于每个披萨计算平均

HDU 4924 Football Manager(状压DP)

题目连接 : http://acm.hdu.edu.cn/showproblem.php?pid=4924 题意 : n(<=20)个人选出11个人作为首发组成a-b-c阵容,每个人都有自己擅长的位置,并且每个人和其他人会有单向的厌恶和喜欢关系,每个人对于自己擅长的位置都有两个值CA和PA,有喜欢或者厌恶关系的两个人在一起也会影响整个首发的CA总值,要求选出一套阵容使得CA最大,或者CA一样的情况下PA最大. 思路 : 状压搞,dp[s]s的二进制表示20个人中选了那几个人,然后规定选进来的顺序

zoj3802:easy 2048 again(状压dp)

zoj月赛的题目,非常不错的一个状压dp.. 题目大意是一个一维的2048游戏 只要有相邻的相同就会合并,合并之后会有奖励分数,总共n个,每个都可以取或者不取 问最终得到的最大值 数据范围n<=500 , a[i]={2,4,8,16}: 分析: 首先明确一下自动合并的意思,比如原有 8,4,2,进入一个2 就会变成16 所以我们需要记录前面的所有数字..计算了一下发现最大情况,500个16会合成4096 =2^12 显然全部记录是不可能的.那么怎么处理呢 我们发现,只有递减的序列才有可能向前合

【HDU3341】 Lost&#39;s revenge (AC自动机+状压DP)

Lost's revenge Time Limit: 5000MS Memory Limit: 65535KB 64bit IO Format: %I64d & %I64u Description Lost and AekdyCoin are friends. They always play "number game"(A boring game based on number theory) together. We all know that AekdyCoin is t

hdu3681(状压dp)

题意:给你一个n*m的矩阵,'F'是起点.机器人从F出发,走到G可以充电(也可以选择不充,同一个G只能充一次电),走到Y关掉开关,D不能走进,每走一步路(上下左右一格)需要消耗1点电量要求把所有开关关掉,且机器人电量上限最少,并求出该最小电量上限.   充电器数量+开关数量<=15,n,m<=15; 解法:首先我们把充电器和开关当做节点,用bfs求出每个节点之间的距离,然后二分电量,状压dp求解判别式 一开始因为忘记了两个节点之间会存在无法到达的情况,WA了几发,qaq 1 #include&

多校7 HDU5816 Hearthstone 状压DP+全排列

1 多校7 HDU5816 Hearthstone 状压DP+全排列 2 题意:boss的PH为p,n张A牌,m张B牌.抽取一张牌,能胜利的概率是多少? 3 如果抽到的是A牌,当剩余牌的数目不少于2张,再从剩余牌里抽两张,否则全部拿完. 4 每次拿到一张B牌,对boss伤害B[i]的值 5 思路:dp[i]表示状态为i时的方案数 6 先处理出所有状态下的方案,再枚举每种状态,如果符合ans+=dp[i]*剩余数的全排列 7 当前集合里有a张A,b张B,那么还能取的牌数:a*2-a-b+1 8 9

HDU 4628 Pieces(状压DP)题解

题意:n个字母,每次可以删掉一组非连续回文,问你最少删几次 思路:把所有回文找出来,然后状压DP 代码: #include<set> #include<map> #include<cmath> #include<queue> #include<cstdio> #include<vector> #include<cstring> #include <iostream> #include<algorithm&