C++ 计算网格的domino覆盖层数
我试图解决以下问题: 问题是: 我们希望用矩形(多米诺骨牌)将网格平铺成4个单位高、N个单位长、2个单位乘1个单位(任意方向)。 编写一个程序,将网格的宽度W作为输入,并输出平铺4×W网格的不同方式的数量。 输入: 2. 3. 7 输出: 5. 11 781 我知道这是一个位掩码动态规划问题。 但是,我的方法并没有得到正确的输出。有人能指出我的方法中的错误吗 代码如下:C++ 计算网格的domino覆盖层数,c++,algorithm,C++,Algorithm,我试图解决以下问题: 问题是: 我们希望用矩形(多米诺骨牌)将网格平铺成4个单位高、N个单位长、2个单位乘1个单位(任意方向)。 编写一个程序,将网格的宽度W作为输入,并输出平铺4×W网格的不同方式的数量。 输入: 2. 3. 7 输出: 5. 11 781 我知道这是一个位掩码动态规划问题。 但是,我的方法并没有得到正确的输出。有人能指出我的方法中的错误吗 代码如下: #include <iostream> #include <cstdio> #include <
#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("%d\n", ans);
}
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
使用名称空间std;
int dp[16][4][60];
整数解算(整数掩码,整数d,整数t)
{
如果(t>4),则返回0;
如果(d==0)返回掩码==0;
如果(t==4)返回解算(掩码,d-1,0);
int&ret=dp[mask][t][d];
如果(ret!=-1)
返回ret;
ret=0;
ret+=solve(mask |)(1我还没有花时间完全理解这个问题,但是仅仅看一下代码,这看起来像是一个没有计算的缓存机制。在主循环的每次迭代中,您都将缓存dp
设置为all-1,但在其他任何地方您都不会将其内容设置为任何其他内容。然后在solve()中
,您有几个返回0的特殊情况,然后是一个返回几个递归调用之和的主情况;但是这些递归调用也无法合法地返回零以外的任何内容
solve()
似乎缺少两件事:
一种极限情况,其中,对于d、t和mask的某些值,以非递归方式计算数值;以及
在某些情况下,计算值应存储在dp
中
此外,我认为缓存dp
可能应该在main()
中的循环外清除,尽管我不是100%确定。你能花几分钟解释一下这应该做什么吗?链接不会永远持续。对不起,缓存值正在solve()函数内更新。int&ret=dp[mask][t] [d]起作用了。呃,你说得对,对不起。事实上,“return mask==0”也会返回非零值。这就是我早上喝咖啡前回答问题的结果。