多边形游戏(动态规划)

多边形游戏(动态规划)


理论和解题步骤有两位大佬说的很好,我就不卖弄了,直接贴他们的,我注释课本中的代码是什么意思。

理论支持——点这里

超超超超级详细解题步骤——点这里

#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];	//存所有边,即各个边所代表的*或+
};

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值