[英]4 by 3 lock pattern
我遇到了这个问题 。
要求计算特定长度的锁定模式可以在4x3网格中进行并遵循规则的方式的数量。 可能有一些点不得包含在路径中
有效模式具有以下属性:
可以使用它第一次触摸的点序列(以与绘制图案相同的顺序)来表示图案,从(1,1)到(2,2)的图案与图案不同从(2,2)到(1,1)。
对于模式表示中的每两个连续点A和B,如果连接A和B的线段通过其他一些点,则这些点也必须在序列中并且在A和B之前,否则模式将无效。 例如,以(3,1)然后(1,3)开头的模式表示是无效的,因为段经过(2,2),它没有出现在(3,1)之前的模式表示中,并且正确该模式的表示为(3,1)(2,2)(1,3)。 但模式(2,2)(3,2)(3,1)(1,3)是有效的,因为(2,2)出现在(3,1)之前。
在模式表示中,我们不会多次提及相同的点,即使模式将通过另一个有效的段再次触及此点,并且模式中的每个段必须从一个点到另一个点,该模式没有之前触摸它可能会经过一些已经出现在模式中的点。
模式的长度是模式表示中每两个连续点之间的曼哈顿距离的总和。 两点(X1,Y1)和(X2,Y2)之间的曼哈顿距离是| X1-X2 | + | Y1 - Y2 | (其中| X |表示X的绝对值)。
模式必须至少触及两点
我的方法是蛮力,循环点,从点开始并使用递归递减长度直到达到零长度然后将组合数加1。
有没有办法在数学方程中计算它或者有更好的算法?
更新:这是我所做的,它给出了一些错误的答案! 我认为问题在于isOk
功能! notAllowed
是不允许的点的全局位掩码。
bool isOk(int i, int j, int di,int dj, ll visited){
int mini = (i<di)?i:di;
int minj = (j<dj)?j:dj;
if(abs(i-di) == 2 && abs(j-dj) == 2 && !getbit(visited, mini+1, minj+1) )
return false;
if(di == i && abs(j - dj) == 2 && !getbit(visited, i,minj+1) )
return false;
if(di == i && abs(j-dj) == 3 && (!getbit(visited, i,1) || !getbit(visited, i,2)) )
return false;
if(dj == j && abs(i - di) == 2 && !getbit(visited, 1,j) )
return false;
return true;
}
int f(int i, int j, ll visited, int l){
if(l > L) return 0;
short& res = dp[i][j][visited][l];
if(res != -1) return res;
res = 0;
if(l == L) return ++res;
for(int di=0 ; di<gN ; ++di){
for(int dj=0 ; dj<gM ; ++dj){
if( getbit(notAllowed, di, dj) || getbit(visited, di, dj) || !isOk(i,j, di,dj, visited) )
continue;
res += f(di, dj, setbit(visited, di, dj), l+dist(i,j , di,dj));
}
}
return res;
}
我对另一个问题的回答也可以适应这个问题。
设f(i,j,visited,k)完成部分模式的方式数,当我们当前在节点(i,j)时,已经访问了访问集中的顶点并且到目前为止已经走了一个路径长度k个。 我们可以将访问表示为位掩码。
我们可以通过尝试所有可能的下一步移动来递归计算f(i,j,visited,k)并应用DP来重用子问题解决方案:
f(i,j,visited,L)= 1
如果k> L,则f(i,j,visited,k)= 0
f(i,j,visited,k)= sum(可能的移动(i',j'):f(i',j',访问UNION {(i',j')},k + dis((i, j),(i',j')))
可能的移动是那些跨越多个被访问顶点然后以单向(并且不被禁止)结束的移动。
如果D是禁止顶点的集合,问题的答案是
sum((i,j)不在D:f(i,j,{(i,j)},L))。
运行时类似于O(X ^ 2 * Y ^ 2 * 2 ^(X * Y)*最大可能长度)。 我想最大可能的长度实际上远低于1000 。
更新:我实施了这个解决方案,它被接受了。 我用以下方式列举了可能的移动:假设我们在点(i,j)并且已经访问了所访问的顶点集。 枚举所有不同的互质对(dx,dy)0 <= dx <X和0 <= dy <Y。然后找到最小的k,其中P_k =(i + k dx,j + k dy)仍然是有效网格点并且P_k没有访问过 。 如果不禁止P_k,则为有效移动。
最大可能路径长度为39。
我正在使用大小为3 * 4 * 2 ^ 12 * 40的DP阵列来存储子问题结果。
可以使用组合的一些属性来优化强力方法:
使用镜像(水平,垂直或两者),您可以为每个找到的组合生成4种组合(水平或垂直线除外)。 也许你只能考虑从一个象限开始的组合。
您通常可以通过平移生成相同长度的其他组合(移动组合)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.