多边形游戏(动态规划)
理论和解题步骤有两位大佬说的很好,我就不卖弄了,直接贴他们的,我注释课本中的代码是什么意思。
理论支持——点这里
超超超超级详细解题步骤——点这里
#include <iostream>
using namespace std;
#define vertex 100 //顶点个数
#define edge 100 //边的个数
class Solution {
public:
//变量解释: n:顶点个数 i:起始顶点 s:断开位置 j:链中元素个数
//minf: maxf:
void MinMax( int n, int i, int s, int j, int &minf, int &maxf ) {
//在op[i+s]处断开,因为第i个顶点后面那条边(顺时针)是编号为i+1的边
int e[4]; //存 两边最大值最小值乘积
int a = m[i][s][0], b = m[i][s][1]; //a,b分别存链左半部分的最小值和最大值
int r = ( i + s - 1 ) % n + 1; //断开位置可能会越界,要求余
//int r= ( i + s ) % n;
int c = m[r][j - s][0], d[r][j - s][1]; //c,d分别存链右半部分的最小值和最大值
//如果断开处的符号是+
if( op[r] == '+' ) {
minf = a + c; //最小值是两边最小值相加
maxf = b + d; //最大值同理
} else {
//乘号特别 可能有负数,所以左半部分分别与右半部分相乘
e[0] = a * c;
e[1] = a * d;
e[2] = b * c;
e[3] = b * d;
minf = e[0], maxf = e[0];
//最大值maxf与最小值minf分别取四个乘积中的最大最小值
for( int r = 1; r < 4; r++ ) {
if( minf > e[r] ) {
minf = e[r];
}
if( maxf < e[r] ) {
maxf = e[r];
}
}
}
}
int PolyMax( int n ) { //n为顶点个数
int minf, maxf; //用来存某个断开位置的最大最小值
//j为链的长度 i为起始位置 s为断开位置
//我们设m[i][1][0]与m[i][1][1]的值都为顶点值,所以直接从链长度为2开始
for( int j = 2; j <= n; j++ ) {
for( int i = 1; i <= n; i++ ) {
//断开位置小于链的长度,s=3表示断开位置在起始位置后的第3条边
for( int s = 1; s < j; s++ ) {
//求出当前当前断开位置的最大最小值
MinMax( n, i, s, j, minf, maxf );
//如果该链的最小值大于当前断开位置后的最小值,更新最小值
if( m[i][j][0] > minf ) {
m[i][j][0] = minf;
}
//如果该链的最大值小于当前断开位置后的最大值,更新最大值
if( m[i][j][1] < maxf ) {
m[i][j][1] = maxf;
}
}
}
}
//temp存1开始整条链的最大值
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;
}
private:
//m[vertex][edge][0]代表最小值
//m[vertex][edge][1]代表最大值
int m[vertex][edge][2];
char op[edge]; //存所有边,即各个边所代表的*或+
};