多边形游戏算法的代码实现

 

 

 一、题目
游戏的前提条件:①开始时有一个由n个顶点构成的多边形。②每个顶点被赋予一个整数值。③每个顶点被赋予一个整数值。④所有边依次用整数从1到n进行编号。

 游戏执行步骤:

 游戏的第1步,将一条边删除。

 随后的n-1步按以下方式操作:

     ①选择一条边E以及由E连接着的2个顶点V1和V2。

     ②用一个新的顶点取代边E以及由E连接着的2个顶点V1和V2。

     ③将由V1和V2的整数值通过边E上运算所得的结果赋予新顶点。

 当所有边都被删除时,游戏结束,游戏的得分即为所剩顶点上的整数值。

 

 

 对于给定的多边形,计算最高得分。
二、算法设计思路

最优子结构性质:

设所给的多边形的顶点和边的顺时针序列为:op[1],v[1],op[2],v[2],...,op[n],v[n],其中op[i]表示第i条边所对应的运算符,v[i]表示第i个顶点上的数值(1<=i<=n)。从顶点i(1<=i<=n)开始,长度为j(链中有j个顶点)的顺时针链p(i,j)可表示为:v[i],op[i+1],...,v[i+j-1]。

若这条链p(i,j)的最后一次合并运算在op[i+s](1<=s<=j-1)处,则在op[i+s]处将链分割为两个子链p(i,s)和p(i+s,j-s)。设m1是对子链p(i,s)的任意一种合并方式得到的值,a和b分别所有合并中的最小值和最大值;m2是p(i+s,j-1)的任意一种合并方式得到的值,c和d分别是所有合并中的最大值和最小值;故a<=m1<=b,c<=m2<=d。m=m1 op[i+s] m2是两条子链合并的值;当op[i+s]=’+’时,a+b<=m<=b+d;当op[i+s]=’*’时,由于v[i]可取负数,故min{ac,ad,bc,bd}<=m<=max{ac,ad,bc,bd};所以主链的最大和最小值可由子链的最大和最小值得到。

计算最优值:

设m[i,j,0]是链p(i,j)合并的最小值,m[i,j,1]是最大值。若最优合并在op[i+s]处将p(i,j)分为2个子链p(i,s)和p(i+s,j-s),a=m[i,s,0],b=m[i,s,1],c=m[i+s,j-s,0],d=m[i+s,j-s,1]。

当op[i+s]=’+’时,m[i,j,0]=a+c,m[i,j,1]=b+d;当op[i+s]=’*’,m[i,j,0]=min{ac,ad,bc,bd},m[i,j,1]=max{ac,ad,bc,bd}。

 

设p(i,j)在op[i+s]处断开的最大值为maxf(i,j,s),最小值为minf(i,j,s),则
由于最优断开位置s有1<=s<=j-1的j-1种情况,所以
初始边界值为当只有一个顶点时m[i,1,0]=v[i],m[i,1,1]=v[i]。

 

三、代码

int polygonGame(int v[],char op[],int n){

int m[n+1][n+1][2];

int minf[n+1][n+1][n];

int maxf[n+1][n+1][n];

for(int e=0;e

for(int f=0;f

for(int g=0;g<2;g++){

m[e][f][g]=0;

}

}

}

for(int i=1;i<=n;i++){                 //当只有一个顶点时,最大最小值都为该顶点的值

m[i][1][0]=v[i];

m[i][1][1]=v[i];

}

for(int j=2;j<=n;j++){             //j表示链长

for(int i=1;i<=n;i++){          //i表示首次删除的边的序号

int min,max;               //链从s处断开的最大值与最小值

for(int s=1;s<=j-1;s++){    //s表示链p(i,j)断开的位置

int k=(i+s-1)%n+1;      //i+s有可能会超过n,要回绕

int a=m[i][s][0];

int b=m[i][s][1];

int c=m[k][j-s][0];

int d=m[k][j-s][1];

if(op[k]=='+'){

minf[i][j][s]=a+c;

maxf[i][j][s]=b+d;

}

else{

int array[4]={a*c,a*d,b*c,b*d};

minf[i][j][s]=array[0];maxf[i][j][s]=array[0];

for(int m=1;m<4;m++){

if(minf[i][j][s]>array[m])

minf[i][j][s]=array[m];

if(maxf[i][j][s]

maxf[i][j][s]=array[m];

}

}

min=minf[i][j][s];max=maxf[i][j][s];

}

if(m[i][j][0]>min)     //找出当i一定,s变化时的最大最小值

m[i][j][0]=min;

if(m[i][j][1]

m[i][j][1]=max;

}

}

int count=m[1][n][1];

for(int i=2;i

if(count

count=m[i][n][1];

}

}

return count;

}

你可能感兴趣的:(多边形游戏算法的代码实现)