传送门:http://poj.org/problem?id=2411

题目简述

有一个\(W\)行\(H\)列的广场,需要用\(1*2\)小砖铺满,小砖之间互相不能重叠,问

有多少种不同的铺法?

输入数据:

只有一行\(2\)个整数,分别为\(W\)和\(H\),\((1<=W,H<=11)\)

输出数据:

只有\(1\)个整数,为所有的铺法数。


妥妥状压

我们向上或者向右放砖头。

为什么呢?

令\(dp[i][j]\)代表\(i\)行\(j\)状态的方案数(\(j\)中的\(1\)代表这个位置在此行时是否被覆盖,不论它是被自己或者别人覆盖的)

此时当前行的\(0\)即可以约束下一行,向上放的过程。向右放即在本行处理。

处理的时候小心一点

code

#include <cstdio>
#include <cstring>
#define ll long long
const int N=12;
ll dp[N][1<<N];//dp[i][j]表示第i行j状态方案数
ll t[1<<N];
int m,n;
//其中,0代表在当前行时没有覆盖,1代表已经覆盖
//行数,上一行的状态,第几个位置,是否被左边照看,当前数字
void dfs(int line,int l_li,int dep,int is,int tt)
{
    if(dep==m+1)
    {
        dp[line][tt]+=dp[line-1][l_li];
        return;
    }
    int flag=!(l_li>>(m-dep)&1);//是否需要看上一行的
    if(is&&!flag)
        dfs(line,l_li,dep+1,0,tt<<1|1);
//被上一个看且不看上一行
    if(!is&&flag)
        dfs(line,l_li,dep+1,0,tt<<1|1);
//没被上一个看且要看上一行
    if(!is&&!flag)
    {
        if(dep!=m) dfs(line,l_li,dep+1,1,tt<<1|1);
        dfs(line,l_li,dep+1,0,tt<<1);
    }
//没被上一个看且不看上一行
}

int main()
{
    scanf("%d%d",&n,&m);
    while(m!=0&&n!=0)
    {
        memset(dp,0,sizeof(dp));
        dp[0][(1<<m)-1]=1;
        int cnt=0;
        t[++cnt]=(1<<m)-1;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=cnt;j++)
                dfs(i,t[j],1,0,0);
            cnt=0;
            for(int j=0;j<(1<<m);j++)
                if(dp[i][j])
                    t[++cnt]=j;
        }
        printf("%lld\n",dp[n][(1<<m)-1]);
        scanf("%d%d",&n,&m);
    }
    return 0;
}

2018.5.10

POJ 2411 解题报告的更多相关文章

  1. POJ 1001 解题报告 高精度大整数乘法模版

    题目是POJ1001 Exponentiation  虽然是小数的幂 最终还是转化为大整数的乘法 这道题要考虑的边界情况比较多 做这道题的时候,我分析了 网上的两个解题报告,发现都有错误,说明OJ对于 ...

  2. poj分类解题报告索引

    图论 图论解题报告索引 DFS poj1321 - 棋盘问题 poj1416 - Shredding Company poj2676 - Sudoku poj2488 - A Knight's Jou ...

  3. POJ 1003 解题报告

    1.问题描述: http://poj.org/problem?id=1003 2.解题思路: 最直观的的想法是看能不能够直接求出一个通项式,然后直接算就好了, 但是这样好水的样子,而且也不知道这个通项 ...

  4. POJ 1004 解题报告

    1.题目描述: http://poj.org/problem?id=1004 2.解题过程 这个题目咋一看很简单,虽然最终要解出来的确也不难,但是还是稍微有些小把戏在里面,其中最大的把戏就是float ...

  5. POJ 1005 解题报告

    1.题目描述   2.解题思路 好吧,这是个水题,我的目的暂时是把poj第一页刷之,所以水题也写写吧,这个题简单数学常识而已,给定坐标(x,y),易知当圆心为(0,0)时,半圆面积为0.5*PI*(x ...

  6. POJ 3414 解题报告!

    原题: Pots Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 13227 Accepted: 5550 Special Jud ...

  7. 广大暑假训练1 E题 Paid Roads(poj 3411) 解题报告

    题目链接:http://poj.org/problem?id=3411 题目意思:N个city 由 m 条路连接,对于一条路(假设连接Cityia和 Cityb),如果从Citya 去 Cityb的途 ...

  8. POJ旅行商问题——解题报告

    旅行商问题 总时间限制: 1000ms 内存限制: 65536kB 描述 某国家有n(1<=n<=10)座城市,给定任意两座城市间距离(不超过1000的非负整数).一个旅行商人希望访问每座 ...

  9. POJ 2182 解题报告

    Lost Cows Time Limit: 1000 MS Memory Limit: 65536 KB Description N (2 <= N <= 8,000) cows have ...

随机推荐

  1. Miner.java 爬虫启动类

    Miner.java 爬虫启动类 package com.iteye.injavawetrust.miner; import java.util.concurrent.ThreadPoolExecut ...

  2. 文件I/O实践(2) --文件stat

    功能:获取文件元数据 #include <sys/types.h> #include <sys/stat.h> #include <unistd.h> int st ...

  3. (NO.00001)iOS游戏SpeedBoy Lite成形记(二十八):增加排行榜功能

    游戏大体上基本也就完成了,还差一个排行榜.否则如何激励各位选手创造新纪录呢? 排行榜功能也没什么难的,不过需要一点点排序的算法上的考虑. 这里我们把排行榜记录数据和排序都放在GameState类中,在 ...

  4. 手把手带你做一个超炫酷loading成功动画view Android自定义view

    写在前面: 本篇可能是手把手自定义view系列最后一篇了,实际上我也是一周前才开始真正接触自定义view,通过这一周的练习,基本上已经熟练自定义view,能够应对一般的view需要,那么就以本篇来结尾 ...

  5. IntelliJ Idea + Maven + Junit

    Caculate.java package com.yxj.TestJunit; /** * Created by ubd on 15-4-17. */ public class Caculate { ...

  6. 《java入门第一季》之面向对象(多态向下转型)

    上一篇博客(http://blog.csdn.net/qq_32059827/article/details/51328638)最后对多态的弊端做了显示,这里解决这个弊端.如下: /* 多态的弊端: ...

  7. Java-Enumeration总结

    纸上得来终觉浅,绝知此事要躬行  --陆游    问渠那得清如许,为有源头活水来  --朱熹 Enumeration(枚举)接口的作用和Iterator类似,只提供了遍历Vector和HashTabl ...

  8. kettle简介(整体架构,运行方式,使用方法)

    项目负责人Matt的说法:把各种数据放到一个壶里,然后呢,以一种你希望的格式流出.呵呵,外国人都很有联想力.看了提供的文档,然后对发布程序的简单试用后,可以很清楚得看到Kettle的四大块: Chef ...

  9. This version of the rendering library is more recent than your version of ADT plug-in. Please update

    预览layout.xml文件时提示: This version of the rendering library is more recent than your version of ADT plu ...

  10. 用C语言绘制一条标准的余弦曲线

    #include<stdio.h> #include<math.h> int main() { double y; int x,m; for(y=1;y>=-1;y-=0 ...