计算网格的多米诺骨牌覆盖物的数量
Calculate number of domino-coverings for a grid
我正试图在SPOJ GNY07H上解决这个问题:问题是:
我们希望用矩形(多米诺骨牌)2个单位乘1个单位(在任一方向)平铺一个高4个单位、长N个单位的网格
编写一个程序,将网格的宽度W作为输入,并输出平铺4乘W网格的不同方式的数量
输入:2.3.7
输出:5.11781
我知道这是一个位掩码动态编程问题。但是,我的方法并没有得到正确的结果。有人能指出我方法中的错误吗。
这是代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <cmath>
#include <climits>
using namespace std;
int dp[16][4][60];
int solve(int mask, int d, int t)
{
if(t > 4) return 0;
if(d == 0) return mask == 0;
if(t == 4) return solve(mask, d-1, 0);
int &ret = dp[mask][t][d];
if(ret != -1)
return ret;
ret = 0;
ret += solve(mask|(1<<t), d, t+1) + solve(mask, d, t+2);
return ret;
}
int main()
{
int i, j, k, l, n, w;
scanf("%d", &n);
while(n--)
{
memset(dp, -1, sizeof(dp));
scanf("%d", &w);
int ans = solve(0, w, 0);
printf("%dn", ans);
}
return 0;
}
方法是这样的:
我一排排地工作。在每一行,对于一列,我尝试先水平和垂直放置瓷砖mask属性告诉哪些列已经填充到行+1中。因此,当瓦片水平放置在行时,则第1行的掩码=遮罩|(1<<列(t)),否则保持不变。我用这种方式计算可能性的总数。递归的停止条件是当掩码为0时,行(在程序中为d),即行变为0。当填充该级别的所有列时,我们减少行(d)。
我还没有花时间完全理解这个问题,但只看代码,这看起来像是一种没有计算的缓存机制。在主循环的每次迭代中,您都将缓存dp
设置为all-1,但在其他任何地方都不会将其内容设置为任何其他内容。然后在solve()
中,有几个特殊情况返回0,然后是一个主要情况返回几个递归调用的总和;但是这些递归调用也没有办法合法地返回除零以外的任何值。
solve()
似乎缺少两件事:
- 一种极限情况,其中,对于d、t和掩码的某些值,数值是非递归计算的;以及
- 在某个时刻,计算出的值应该存储在
dp
中
此外,我认为缓存dp
可能应该在main()
的循环外清除,尽管我不能100%确定。
相关文章:
- 多态性和功能结合
- 具有默认模板参数的多态类的模板推导失败
- 处理多个异常集合的C++方法
- 找不到成员对象:没有名为get_event()的成员,也处理多态性和向量
- 尝试通过多个向量访问变量时,向量下标超出范围
- 在没有太多条件句的情况下,我如何避免被零除
- 在C++中使用cURL和多线程
- Ardunio UNO解决了多个重叠的定时器循环
- 在计算中使用二的幂有多有利可图
- MSVC多行宏编译器错误
- 通过多个头文件使用常量变量
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- 多米诺骨牌计划。我不知道如何将我的矢量拉到空白中以打印出来
- 如何为多个模拟引脚编写功能?(阿杜伊诺)
- 使用 2x1 和 1x2 多米诺骨牌平铺具有禁止位置的 2xN 网格的方法数量
- 计算网格的多米诺骨牌覆盖物的数量
- C++生成多米诺骨牌的随机数
- 最长的多米诺骨牌链/序列
- 我不能有一个将多个整数作为参数的构造函数方法/原型吗?阿杜伊诺
- 多变量埃尔米特样条