• DFS(一):砌墙问题


    问题描述

    使用两种砖头砌墙,砖头A宽为2,高为1,砖头B宽为3,高为1,用这两种砖头砌一面宽为W,高为H的墙。

    为了使墙牢固性高,要求每种砖只能横向摆放,不能竖起来,且除了两侧以外,不能出现上下对齐的砖缝,请参考下图: 

         

    上图允许

    上图不允许

    下图展示了宽为13,高为5的墙的一种砌法

    对于给定的宽度W,高度H,请问有多少种砌法?

    解决方案

    该问题可以转化为搜索问题,使用深度优先搜索即可解决。

    具体思路是:将墙转化为2维平面坐标系,使用二维字符数组记录砖缝的位置,放置砖块时,判断是否可行,不行则回溯。

    从源点出发,向右上方进行递归搜索,直到搜索到对角顶点处,便得到了一种砌法,程序结束时,所有的砌法都已经被搜索到。

    代码实现(c++)

    #include<iostream>
    #include<string>
    #define yes 1
    #define no 0
    using namespace std;
    static int kind = 0;//可行的方案数 
    static int H,W;
    //判断是否可以在该位置放置砖块 
    int IsOk(string abv, int w){
        if(w>W)
            return no;
        else if (w==W)
            return yes;
        return (abv[w]-'0')?no:yes;
    }
    //深搜 
    void dfs(int h, int w, string above[]){
        if(h == (H+1)){   //搜索的出口,输出合适的方案 
            kind ++;
            for(int i=1;i<=H;i++)
                cout<<above[i]<<endl;
            cout<<"---------------"<<endl;
            return;
        }
        for(int i = 2; i <=3; i++){
            if(IsOk(above[h-1], w+i)){
                above[h][w+i] = '1';   //放置砖块,标记砖缝位置。 
                if((w+i)==W)
                    dfs(h+1, 0, above);
                else 
                    dfs(h, w+i, above);
                above[h][w+i] = '0';  //回溯,搜索另一条路径。 
            }
        }
        return;
    }
    
    int main(){
        cin>>W;
        cin>>H;
        string above[H+1];
        for(int i = 0; i <= H; i++){   //初始化字符串数组,用来记录砖缝位置。 
            above[i] = '1';
            for(int j = 1; j <= W; j++)
                above[i] += '0';
            }
        dfs(1, 0, above);
        cout<<kind<<endl;
    }

    运行结果

    输入:宽度9,高度5。

    输出:14

  • 相关阅读:
    平方和公式
    $bootpuss$切不掉的「水题」
    回滚莫队初步
    [***]HZOJ 柱状图
    HZOJ 走格子
    HZOJ 旋转子段
    [***]HZOJ 优美序列
    [***]HZOJ 跳房子
    HZOJ 矩阵游戏
    模板—K-D-tree(P2479 [SDOI2010]捉迷藏)
  • 原文地址:https://www.cnblogs.com/zz-zhang/p/11527623.html
Copyright © 2020-2023  润新知