Algorithm “的算法”;“拿起数字游戏”;
我正在努力寻找解决方案,但我对此一无所知 RobotA和RobotB选择N个数字的排列作为开始。罗博塔先选,他们轮流选。每个回合,机器人只能从排列中选择剩余的任何一个数字。当剩余的数字形成递增序列时,游戏结束。选择最后一个回合的机器人(之后序列增加)赢得游戏 假设双方都发挥最佳状态,谁会赢 示例1: 示例2:Algorithm “的算法”;“拿起数字游戏”;,algorithm,permutation,puzzle,Algorithm,Permutation,Puzzle,我正在努力寻找解决方案,但我对此一无所知 RobotA和RobotB选择N个数字的排列作为开始。罗博塔先选,他们轮流选。每个回合,机器人只能从排列中选择剩余的任何一个数字。当剩余的数字形成递增序列时,游戏结束。选择最后一个回合的机器人(之后序列增加)赢得游戏 假设双方都发挥最佳状态,谁会赢 示例1: 示例2: 有没有已知的算法可以解决这个问题?请给我任何建议或想法,在哪里看将是真正的感谢 看起来是个问题 我想这项任务有更快的解决方案。我会想。 但我可以给你一个O(N!*N^2)复杂度的解决方案
有没有已知的算法可以解决这个问题?请给我任何建议或想法,在哪里看将是真正的感谢 看起来是个问题 我想这项任务有更快的解决方案。我会想。 但我可以给你一个O(N!*N^2)复杂度的解决方案 首先,请注意,从N置换中选取的编号等效于以下内容:
Boolean F(X)
{
Let K be length of permutation with code X.
if you already compute F for argument X return previously calculated result;
if X == 1 2 .. K return 0;
Boolean result = 0;
for i = 1 to K do
{
Y code of permutation get from X by picking number on position i.
if (F(y) == 0)
{
result = 1;
break;
}
}
Store result as F(X);
return result;
}
对于每个参数,我们只计算这个函数一次。有一个!长度为1,2的排列!长度为2.的排列。。N长度为N的置换。对于置换长度K,我们需要进行O(K)运算来计算。因此复杂性将是O(1*1!+2*2!+…N*N!)=给定一个不同数字的序列
w
,让N(w)
是w
的长度,让L(w)
是w
中最长递增子序列的长度。例如,如果
w = 3 5 8 1 4
然后N(w)=5
和L(w)=3
当L(w)=N(w)
,或者相当于N(w)-L(w)=0
时,游戏结束
向后操作游戏,如果在RobotX的回合N(w)-L(w)=1
,则最佳游戏是移除不在最长递增子序列中的唯一字母,从而赢得游戏
例如,如果w=1 7 3
,则N(w)=3
和L(w)=2
,最长递增子序列为1 3
。删除7
会增加顺序,确保删除7
的玩家获胜
回到上一个例子,w=3 5 8 1 4
,如果1
或4
被移除,那么对于产生的排列u
我们有N(u)-L(u)=1
,因此移除1
或4
的玩家肯定会输给有能力的对手。但是,任何其他比赛都会导致胜利,因为它会迫使下一名球员移动到一个失败的位置。在这里,最佳策略是删除3
、5
或8
中的任何一个,之后N(u)-L(u)=2
,但在下一步之后N(v)-L(v)=1
沿着这些思路进行的进一步分析应该会为任何一方带来最佳策略
我所知道的最近的数学游戏是单调序列游戏。在单调序列游戏中,两个玩家从某个固定的有序集合(例如,
1,2,…,N
)中交替选择序列的元素。当结果序列包含长度A
的上升子序列或长度D
的下降子序列时,游戏结束。这个游戏起源于鄂尔多斯和塞克勒斯的一个定理,其中有一个很好的解释,布鲁斯·萨根的这篇文章也是一个很好的参考
如果你想更多地了解一般的博弈论,或者这类游戏,那么我强烈推荐Berlekamp、Conway和Guy为你的数学游戏设计的获胜方式。我相信,第三卷是针对这类游戏的。这里是智慧之风算法的Python代码。它打印出罗博塔的胜利
import itertools
def moves(p):
if tuple(sorted(p)) == p:
return
for i in p:
yield tuple(j - (j > i) for j in p if j != i)
winning = set()
for n in range(6):
for p in itertools.permutations(range(n)):
if not winning.issuperset(moves(p)):
winning.add(p)
for p in sorted(winning, key=lambda q: (len(q), q)):
print(p)
很抱歉没有真正的解决方案,但我发现如果你保持英语基础,更多的人会理解。把英语作为第二语言,我也觉得有必要使用像“排列”这样的大词,但简单地说“重新排列”会使你更容易阅读和理解你要找的东西。谢谢你的建议。@user85569我不同意。没有理由使语言哑口无言。尤其是当置换是数学和计算机科学中的一个常用词时。@user85569,置换是一个标准的数学术语。它不能用重新安排来代替。@Yuriy Faktorovich我没有用英语教数学或计算机科学。所以我不得不在谷歌上查这个词,知道他想说什么。它阻碍了这一过程,因为我相信很多人都不是以英语为第一语言,也不是用英语教学的。是一个让每个人都更容易理解的建议。。。因为这是互联网…我不认为这是正确的方式。这将是非常缓慢和非常难以实现的,因此游戏是最佳的。@IVlad你有更好的建议吗?Minimax或alpha-beta修剪是探索的标准方法
w = 3 5 8 1 4
import itertools
def moves(p):
if tuple(sorted(p)) == p:
return
for i in p:
yield tuple(j - (j > i) for j in p if j != i)
winning = set()
for n in range(6):
for p in itertools.permutations(range(n)):
if not winning.issuperset(moves(p)):
winning.add(p)
for p in sorted(winning, key=lambda q: (len(q), q)):
print(p)