#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#define MAX 100
//顶点和边顺时针顺序为v[1] op[1] v[2] op[2] v[3]...
int v[MAX];
char op[MAX];
//m[i][j][0]存放自顶点i开始(首次删除第i条边),长度为j的子链长度的最小值
//m[i][j][1]存放自顶点i开始(首次删除第i条边),长度为j的子链长度的最大值
int m[MAX][MAX][2];
void minMax(int n, int i, int s, int j, int &max, int &min)
// 多边形顶点数为n,子段长度为j,求自顶点i开始,在长度为s处截断,截断处运算符为op
//的子段最大值max,最小值min
{
int e[4];
int min1 = m[i][s][0], max1 = m[i][s][1]; //在s处分割后,段1最大值与最小值
int r = (i+s-1)%n +1 ; //段2实际起始顶点编号,如果r=(i+s)%n,会出现编号0
int min2 = m[r][j-s][0], max2=m[r][j-s][1]; //在s处分割后,段2最大值与最小值
if(op[r-1]=='+') //如果是 +
{
max = max1 + max2;
min = min1 + min2;
}
else //如果是 *
{
e[0] = min1 * min2; e[1] = min1 * max2;
e[2] = max1 * min2; e[3] = max1 * max2;
min = max = e[0];
int c;
for(c=1; c<4; c++)
{
if(min>e[c])
min = e[c];
if(max<e[c])
max = e[c];
}
}
}
int PloyMax(int n)
//顶点数为n的多边形最终剩下的最优值
{
int i, j, s;
int max, min;
for(i=1; i<=n; i++)
m[i][1][0] = m[i][1][1] = v[i]; //初始边界值
for(j=2; j<=n; j++) //子段长度分别为2,3...n
for(i=1; i<=n; i++) //从第i个顶点开始
for(s=1; s<j; s++) //在长度为s处截断
{
minMax(n, i, s, j, max, min);
if(m[i][j][0]>min)
m[i][j][0] = min;
if(m[i][j][1]<max)
m[i][j][1] = max;
}
int temp = m[1][n][1]; //假设删除第一条边时得到最优值
for(i=2; i<=n; i++)
if(temp<m[i][n][1])
temp = m[i][n][1];
return temp;
}
int main()
{
int n;
printf("输入顶点数:");
scanf("%d", &n);
int i;
for(i=1; i<=n; i++)
{
printf("顶点%d数值:", i);
scanf("%d", &v[i]);
printf("边%d运算符:", i);
getchar();
scanf("%c", &op[i]);
}
int max = PloyMax(n);
printf("最优值为%d\n", max);
return 0;
}
多边形游戏
最新推荐文章于 2022-04-23 17:39:41 发布