- 博主简介:一个爱打游戏的计算机专业学生
- 博主主页: @夏驰和徐策
- 所属专栏:算法设计与分析
1.什么是多边形游戏?
对于多边形游戏,一种特定类型的玩法,即在给定的简单多边形上进行移动、删除顶点或边,并根据规则计算得分的游戏。这类游戏可以涉及到不同的规则和目标,具体的玩法可能有所不同,但其基本思想是根据给定的操作方式,通过选择和移动顶点或边,使得得分最高。
在这类游戏中,玩家需要仔细观察多边形的形状和特征,并根据规则进行决策。常见的操作可能包括选择一个顶点或边,将其移动到新的位置,或者删除它,然后重新计算得分。得分的计算方式可能与多边形的属性有关,比如边长、角度、对称性等。玩家需要根据规则进行合理的选择和操作,以使得得分最高。
这类多边形游戏可以提供一种锻炼逻辑思维和问题解决能力的机会,同时也能够增强对数学概念的理解和运用。玩家需要分析多边形的特征,并基于自己的判断和策略进行操作,以达到最优解或最高得分。这样的游戏既能够带来娱乐乐趣,又能够促进数学思维的发展。
2.怎么证明最优子结构?
我的理解:
这段证明的主要目的是展示多边形游戏问题满足最优子结构性质。为了说明这一点,作者通过具体的描述和推理,给出了关于链的合并和分割的情况,并证明了子链的最优性与主链的最优性之间的关系。
在证明中,给定了一个顺时针序列的多边形,其中包含了顶点和边的信息。链表示从某个顶点开始的一段顺时针的路径,用来表示游戏中的一种操作序列。作者通过将链分割为两个子链,并定义了最小值和最大值的概念来讨论链的合并方式和计算结果。
根据作者的定义,对于主链和子链的合并方式以及对应的计算结果,存在最小值和最大值。在某些情况下,最小值和最大值可以由子链的最小值和最大值得到,而在其他情况下,最小值和最大值则需要通过比较不同子链的值来确定。作者通过这些推理和比较的过程,说明了主链的最优性与子链的最优性之间的关系。
综上所述,通过分析链的合并和分割的方式以及计算结果的最小值和最大值,作者证明了多边形游戏问题满足最优子结构性质。这意味着可以使用动态规划等算法来解决多边形游戏问题,并通过组合子问题的最优解来得到整个问题的最优解。
具体的说:
在这个证明中,我们需要证明多边形游戏问题具有最优子结构性质。下面是证明的具体过程和思路:
1. 首先,我们需要定义一些符号和术语:
- Op1, ML1, op12, 2121, opl7, HU7:这些表示多边形中的顶点和边的顺时针序列,其中opl表示第i条边对应的运算符,以m表示第i个顶点上的数值。
- p(i, s):表示从顶点i开始长度为s的顺时针链,用来表示游戏中的一种操作序列。
2. 我们考虑将链p(i, s)在oplits]处分割为两个子链p(i, t)和p(t+1, s),其中t为oplits]对应的位置。
- 这样的分割可以得到两个子问题,分别是对子链p(i, t)和p(t+1, s)进行合并的最优解。
- 设子链p(i, t)的任意一种合并方式得到的值为m1,a和b分别是所有可能合并方式得到的最小值和最大值。
- 同样地,设子链p(t+1, s)的任意一种合并方式得到的值为m2,c和d分别是所有可能合并方式得到的最小值和最大值。
3. 我们需要证明两种情况下的最优子结构性质:
- 当oplits]为正运算符时:
- 我们观察到m1的最小值和最大值都必须小于等于m2的最小值和最大值,即a ≤ m1 ≤ b,c ≤ m2 ≤ d。
- 这意味着通过主链p(i, s)的最优解可以推导出子链p(i, t)和p(t+1, s)的最优解,且最大值对应最大子链的最大值,最小值对应最小子链的最小值。
- 当oplits]为负运算符时:
- 这种情况下,我们无法保证子链的最大值相乘能得到主链的最大值。
- 但是,最大值仍然会出现在边界点上,即min{ac, ad, bc, bd} ≤ m ≤ max{ac, ad, bc, bd}。
- 这意味着主链的最大值和最小值可以由子链的最大值和最小值得到,虽然最大值不一定是子链的最大值的乘积,最小值不一定是子链的最小值的乘积。
4. 综上所述,通过对链的分割和合并方式以及计算结果的最小值和最大值进行推理和比较,我们可以得出结论:多边形游戏满足最优子结构性质
3.递归方程的推导
4.算法描述
void MinMax(int n,int i,int s,int j,int& minf,int& maxf)
{
int e[4];
int a=m[i][s][0],b[i][s][1],r(i+s-1)%n+1,c=m[r][j-s][0],d=m[r][j-s][1]
if(op[r]=='t');
{
minf=a+c;
maxf=b+d;
}
else
{
e[1]=a+c;
e[2]=a*d;
e[3]=b*c;
e[4]=b*d;
minf=e[1];
maxf=e[1];
for(int r=2;r<5;r++)
{
if(minf>e[r])
{
minf=e[r];
}
if(maxf<e[r])
{
max=e[r];
}
}
}
int PolyMax(int n)
{
int minf,maxf;
for(int j=2;j<=n;j++)
{
for(int i=1;i<=n;i++)
{
for(int s=1;s<j;s++)
{
MinMax(n,i,s,j,minf,maxf,m,op)
if(m[i][j][0]>minf)
{
m[i][j][0]=minf;
}
if(m[i][j][1]<maxf)
m[i][j][1]=maxf;
}
}
}
int temp=m[1][n][1];
for(int i=2;i<=n;i++)
{
if(temp<m[i][n][1])
{
temp=m[i][n][1]
}
}
}
return temp;
}
我的理解:
这段代码是用来求解多边形游戏中的最优得分的函数。函数名为MinMax,接受一些参数,包括多边形顶点个数n、起始位置i、子链长度s、结束位置j,以及引用类型的最小值minf和最大值maxf。
代码首先声明了一个大小为4的整型数组e,用于存储计算得到的四种情况下的得分。接下来,根据给定的多边形顶点和边的索引,获取对应的得分值a、b、c、d。
代码中使用了条件语句判断当前操作符是否为't',根据操作符的不同选择不同的计算方式。如果操作符为't',则直接将最小值minf设置为a+c,最大值maxf设置为b+d。否则,通过四种情况下的计算,将得分分别存储到数组e中,并更新最小值minf和最大值maxf。
代码中使用了一个循环遍历数组e,找到最小值和最大值,并将其赋值给minf和maxf。
接下来,代码定义了一个名为PolyMax的函数,用于计算多边形游戏的最优得分。函数内部有一个嵌套的循环结构,用于遍历所有可能的子链长度和位置,并调用MinMax函数计算得分。然后,将得到的最小值和最大值更新到对应的数组m中。
最后,代码通过一个循环找到最终结果的最大值,并将其返回。
总体来说,这段代码是通过遍历和计算得分来求解多边形游戏中的最优结果。它使用了动态规划的思想,通过存储中间结果并利用最优子结构性质,避免了重复计算,从而提高了计算效率。
5.时间复杂度
O(n^3)