首页 > 其他分享 >hdu1400/acwing 291 Mondriaan's Dream

hdu1400/acwing 291 Mondriaan's Dream

时间:2023-09-11 22:23:30浏览次数:54  
标签:cnt int Mondriaan 一行 合法 st Dream dp 291

题意描述:

  给定一块n*m的区域,用1*2的长方形填充,长方形可以横着或竖着摆,问一共有多少种填充方案

具体思路:  

 题意没什么好说的,简单易懂,很经典的一类状态压缩问题(在棋盘中求填充方案)。

 观察数据,满足n,m都比较小,但是搜索的复杂度大到无法接受,考虑使用状态压缩求解此类问题

 首先,肯定是第一步,即对题目给定的图进行初始化,初始化应该怎么搞?观察到若使用横着填的方法填充一行的情况,发现有很多单行中有奇数数量的横向填充方案完全不合法,考虑初始化。即预处理出合理的情况,用桶来记录,稍后再筛选出合法的情况。

 第一步筛选完成了,虽然排除了许多冗余的情况,但是如此大的数据直接dp,两个指数级别的数相乘会导致复杂度完全无法接受,所以考虑第二步初始化,即将本行的状况与上一行进行比对,确定最终到底有几个合法的情况。 

 最后一步进入正题,dp环节,dp环节和为什么这样转移在代码中解释

代码实现:

#include<bits/stdc++.h>
using namespace std;
const int N=1<<13;
long long dp[13][N],n,m;
bool st[N];//桶数组判断合法状态
vector<vector<long long> >G(N);//第二步筛选后的合法状态
int main()
{
    while(cin>>n>>m,n||m)
    {
        for(int i=0;i<(1<<n);i++)
        {
            int cnt=0;bool isvalid=true;//记录当前有几个0
            for(int j=0;j<n;j++)
            {
                if((i>>j)&1)//取出当前为的值,如果当前位为一,之前的cnt记录的"0"的个数清空,接着判断当前状态是否合法
                {
                    if(cnt&1)//如果cnt为偶数,不合法
                    {
                        isvalid=false;
                        break;
                    }
                    cnt=0;//清空不清空差不多
                }
                else cnt++;//当前位为“0”,继续累加
            }
            if(cnt&1) isvalid=false;//判断最后一行是什么情况
            st[i]=isvalid;
        }
        for(int j=0;j<(1<<n);j++)
        {
            G[j].clear();//初始化
            for(int k=0;k<(1<<n);k++)
            {
          //细说st[j|k],关键至极
          //首先,j&k是判断是否是上一行是"1",下一行是"0",因为不是这样就不合法,简言之,只要j&k==1就不合法
          //再就是st[j|k]
          //首先要了解一点,就是k枚举的是上一行的所有状态,所以st[j|k]是什么意思呢
          //明确,st存的是所有合法的状态,如果j|k它不是一个合法的状态,即此时会有奇数个零,那么实际上这个状态它是不合法的,即上一行伸长下来和这一行伸长下去的,这些被伸长或者伸长下去的
          //是不能供横着放的格子放的
          //所以要这样 if((j&k)==0&&st[j|k]) { G[j].push_back(k); } } } memset(dp,0,sizeof(dp)); dp[0][0]=1; for(int i=1;i<=m;i++) { for(int j=0;j<(1<<n);j++) { for(auto k:G[j]) { dp[i][j]+=dp[i-1][k];//当前行的状态的答案是上一行所有可能情况的和 } } } cout<<dp[m][0]<<endl;//答案就是已经填到m行,且当前行没有向下伸长的情况 } return 0; }

 

标签:cnt,int,Mondriaan,一行,合法,st,Dream,dp,291
From: https://www.cnblogs.com/mingloch/p/17694691.html

相关文章

  • POJ2411 Mondriaan's Dream(多米诺密铺问题)
    不妨设\(n,m\)相等,常规的状压DP做法时间复杂度为\(O(n*2^n)\),但是可以通过套用公式使复杂度变为\(O(n^2)\)。具体地,用\(1*2\)的小长方形覆盖\(n*m\)的棋盘的方案数为\[\Large\prod\limits_{j=1}^{\left\lceil\frac{m}{2}\right\rceil}\prod\limits_{k=1}^{\l......
  • Gym102994M Travel Dream
    题意:\(n\)个点的图,找一个有\(k\)个点的的简单环,使其边权和最大。随机黑白染色,拆成两条颜色不同的不相交链,做\(300\)次即可。链的情况是好做的,做完后,预处理\(f_{x,y}\)表示\(x\)到\(y\)的最大距离,枚举两条端点颜色不同的边可以直接合并。链点数\(\leq4\)都是可以直......
  • 「Dreamweaver安装包大全下载」DW软件安装包 新功能介绍
    AdobeDreamweaver2022是Adobe公司全新发布的可视化网页制作编辑软件,DreamweaverCC包含实时检查和CSS设计工具等多项增强功能,可以帮助用户更加轻松地创建和更新桌面平台和移动设备的网页内容,另外,新的元素快速检查功能可以帮助网页设计师速检查、预览及编辑众多的HTML标记等。使......
  • DreamWeaver+WebDav(IIS)配置团队协作开发
    作者:fbysssbasicauthentication因为如果是远程,肯定不能使用windows集成。这时的用户,应该是服务器上自行建立分配的用户(控制面板->用户).  可以通过目录的"安全"来指定每个用户的访问权限. 在Dreamweaver中新建一个站点.设置站点名称/本地根文件夹;远程信息->访问,选WebDav,然......
  • 8.30 模拟赛 光和影(dream) 题解
    概括:大分类讨论。首先有个重要结论,无论是三种操作中的哪一种,他的左儿子仍然在他的左子树内,右儿子在右子树内。同时,旋转一个点一次,对他更上面的点的深度没有影响。以此,我们预处理出一个\(up_{u,0/1}\)表示将\(u\)splay到根上,对左子树和右子树深度的影响,由于上面的结论,这个东......
  • Dreamweaver2021设计DW2021下载安装 中文版直装
    Dreamweaver2021版是一款非常专业的网页设计工具,设计功能强大,集网页制作和网站管理于一体,强大的编辑器让您的工作更轻松!功能介绍:可视化界面:Dreamweaver提供了可视化界面,使得用户可以直接在界面上操作,无需编写代码。代码编辑器:Dreamweaver也提供了代码编辑器,方便用户编辑和调试代码......
  • hdu 4291(矩阵快速幂+循环节)
    AShortproblemTimeLimit:2000/1000MS(Java/Others)    MemoryLimit:32768/32768K(Java/Others)TotalSubmission(s):2487    AcceptedSubmission(s):876ProblemDescriptionAccordingtoaresearch,VIMuserstendtohaveshorterfing......
  • BanG Dream! It's MyGO!!!!! 短评
    BanGDream!It'sMyGO!!!!!小众佳作原创番3d略劝退“低气压美少女乐队番”,不得不说,这个“低气压”可太精髓了整个剧情笼罩在已死乐团CRYCHIC的阴云下,太窒息了Tomori:本作重女,要“组一辈子的乐队”,总是给我一种自闭、不善交流的印象,然而内心活动丰富,有时会把他人的过错归......
  • Adobe Dreamweaver 2022官方版_最新免费版下载安装 官方版特色
    AdobeDreamweaver2021亮点1.快速.灵活的编码借助简化的智能编码引擎,轻松创建.编码和管理动态网站。访问代码提示,用于快速理解和编辑HTML.CSS和其他Web标准。利用视觉辅助功能减少错误,提高网站开发速度。2.通过较少的步骤轻松设置网站使用起始模板更快地启动和运行您的网站,您可以通......
  • #轮廓线dp#HDU 1400 Mondriaan's Dream
    题目传送门分析状压dp会TLE,考虑用轮廓线dp,设\(dp[i][j][S]\)表示现在处理到\((i,j)\)这个位置轮廓线上状态为\(S\)的情况二进制位为1表示左边或者上方有骨牌跨过轮廓线,然后分类讨论转移一下即可代码#include<cstdio>#include<cstring>usingnamespacestd;con......