【动态规划】广场铺砖

来源:互联网 发布:mac 5kplayer下载 编辑:程序博客网 时间:2024/04/27 17:09
有一个 W 行 H 列的广场,需要用 1*2小砖铺盖,小砖之间互相不能重叠,问有多少种不同的铺法?  输入数据: 只有一行 2个整数,分别为 W 和 H,(1<=W,H<=11)  输出数据:   只有 1个整数,为所有的铺法数。  样例:   Floor.in   2 4   Floor.out   5  样例铺法如下图:

一道比较简单的状态压缩型动态规划。
用插头DP实现,此处略去N字……
Accode:

#include <cstdio>#include <cstring>#include <algorithm>typedef long long int64;int64 f[2][0xfff];int status[2][0xfff];int ID[0xfff];int cnt[2];int n, m, pst, ths = 1;inline int get_ID(int S){    if (!ID[S])    {        ID[S] = ++cnt[ths];        f[ths][ID[S]] = 0;        status[ths][ID[S]] = S;    }    return ID[S];}int main(){    freopen("floor.in", "r", stdin);    freopen("floor.out", "w", stdout);    scanf("%d%d", &n, &m);    f[ths][get_ID(0)] = 1;    for (int i = 0; i < n; ++i)    for (int j = 0; j < m; ++j)    {        std::swap(pst, ths);        cnt[ths] = 0;        memset(ID, 0, sizeof(ID));        int x = m - j - 1;        for (int k = 1; k < cnt[pst] + 1; ++k)        {            int64 val = f[pst][k];            int Last = status[pst][k];            if (!j)            {                if (Last & 1) continue;                else Last >>= 1;            }            switch ((Last >> x) & 3)            {            case 0:                f[ths][get_ID(Last | (1 << x))] += val;                f[ths][get_ID(Last | (2 << x))] += val;                break;            case 1: case 2:                f[ths][get_ID(Last & ~(3 << x))] += val;                break;            }        }    }    printf("%I64d", f[ths][get_ID(0)]); //注意输出。    return 0;}


原创粉丝点击