动规-多边形游戏

1.题目描述

多边形游戏大概是这样的:看下面的一幅图:

有一个多边形,节点处是数字,边上是运算符,这里只考虑“+”和“*”两种,两个点的数与他们之间的运算符进行运算后的结果数构成新的节点,这样运算到最后只剩一个数,我们要求得能够运算出的最大的数。

2.代码

#include <stdio.h>
#include <iostream>
using namespace std;

int ***m;
char *op;
void MinMax(int n, int i, int s, int j, int& minf, int& maxf);
int PolyMax(int n);

int main()
{
    int n;
    cout << "请输入数字个数:";
    cin >> n;

    m = new int**[n + 1];

    for (int i = 0; i <= n; i++)
        m[i] = new int*[n + 1];

    for (int i = 0; i <= n; i++)
        for (int j = 0; j <= n; j++)
            m[i][j] = new int[2];//第三维0和1表示最小值和最大值

    op = new char[n];

    //输入循环表达式,必须保证最后输入的一位为运算符
    cout << "请输入表达式:";
    for (int i = 1; i<n; i++) {
        cin >> m[i][1][0];
        m[i][1][1] = m[i][1][0];
        cin >> op[i + 1];
    }
    cin >> m[n][1][0];
    cin >> op[1];
    m[n][1][1] = m[n][1][0];
    int max = PolyMax(n);

    cout << "最大值为:" << max << endl;
    return 0;
}
//求i,j之间的表达式构成的最大值和最小值
void MinMax(int n, int i, int s, int j, int& minf, int& maxf)
{
    //设立一个数组分别用于存储ac,ad,bc,bd
    int e[5];

    int a, b, c, d, r;
    a = m[i][s][0];
    b = m[i][s][1];
    //如果超过了n个元素,回到环的其他位置
    r = (i + s - 1) % n + 1;
    c = m[r][j - s][0];
    d = m[r][j - s][1];

    if (op[r] == ‘+‘) {
        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])
                maxf = e[r];
        }
    }
}

//求1...n之间的表达式构成的最大值和最小值
int PolyMax(int n)
{
    int minf, maxf;
    //通过递推球minf,maxf以及m[i][j][0]和m[i][j][1]
    for (int j = 2; j <= n; j++)
        for (int i = 1; i <= n; i++) {
            //设置最大值和最小值
            m[i][j][0] = -2147483647;
            m[i][j][0] = 2147483648;
            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;
            }
        }
    //通过不同的断链方法,求所有的最大值中的最大值
    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;

}

运算结果:

6480 = 6*(2+8)*9*12

时间: 2025-01-11 19:28:55

动规-多边形游戏的相关文章

【BZOJ3875】【Ahoi2014】骑士游戏 SPFA处理有后效性动规

广告: #include <stdio.h> int main() { puts("转载请注明出处[vmurder]谢谢"); puts("网址:blog.csdn.net/vmurder/article/details/44040735"); } 题解: 首先一个点可以分裂成多个新点,这样就有了图上动规的基础. 即f[i]表示i点被消灭的最小代价,它可以由分裂出的点们更新. 但是这个东西有后效性,所以我们用SPFA来处理它. spfa处理后效性动规 我

【noip 2009】 乌龟棋 记忆化搜索&amp;动规

题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点,游戏要求玩家控制一个乌龟棋子从起点出发走到终点. 乌龟棋中M张爬行卡片,分成4种不同的类型(M张卡片中不一定包含所有4种类型的卡片,见样例),每种类型的卡片上分别标有1.2.3.4四个数字之一,表示使用这种卡片后,乌龟棋子将向前爬行相应的格子数.游戏中,玩家每次需要从所有的爬行卡片中选择一张之前没有使用过的爬行卡片,控制乌龟棋子前

(动规 或 最短路)Help Jimmy(poj 1661)

http://poj.org/problem?id=1661 Description "Help Jimmy" 是在下图所示的场景上完成的游戏. 场景中包括多个长度和高度各不相同的平台.地面是最低的平台,高度为零,长度无限. Jimmy老鼠在时刻0从高于所有平台的某处开始下落,它的下落速度始终为1米/秒.当Jimmy落到某个平台上时,游戏者选择让它向左还是向右跑,它跑动的速度也是1米/秒.当Jimmy跑到平台的边缘时,开始继续下落.Jimmy每次下落的高度不能超过MAX米,不然就会摔死

POJ 2955 Brackets (动规)

Brackets Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 2999   Accepted: 1536 Description We give the following inductive definition of a "regular brackets" sequence: the empty sequence is a regular brackets sequence, if s is a reg

sicily 1091 Maximum Sum (动规)

1 //1091.Maximum Sum 2 //b(i,j) = max{b(i,j-1)+a[j], max(b(i-1,t)+a[j])} (t<j) 3 #include <iostream> 4 using namespace std; 5 6 int main() { 7 int t; 8 cin>>t; 9 while (t--) { 10 int n; 11 cin>>n; 12 int a[n+1]; 13 for (int i = 1; i &

ACM/ICPC 之 经典动规(POJ1088-滑雪)

POJ1088-滑雪 将每个滑雪点都看作起点,从最低点开始逐个由四周递推出到达此点的最长路径的长度,由该点记下. 理论上,也可以将每一点都看作终点,由最高点开始计数,有兴趣可以试试. 1 //经典DP-由高向低海拔滑雪-求最长路 2 //Memory:372K Time:32 Ms 3 #include<iostream> 4 #include<cstring> 5 #include<cstdio> 6 #include<algorithm> 7 using

!HDU 1176--DP--(矩阵动规)

题意:有一个数轴,从0到10,小明开始在5这个位置.现在天上开始掉馅饼,小明每次只能移动单位一的长度,求小明最多能接到多少馅饼. 分析:刚开始接触动态规划,还没有真正理解动规的思维,所以刚开始的dp做法不知道对不对但是TLE了.正确的方法是建立一个以时间为行位置为列的矩阵,最初map[i][j]代表的是第i时刻j位置掉的馅饼的数量,状态转移方程:map[i][j]=map[i][j]+max(map[i+1][j-1],map[i+1][j],map[i+1][j+1]).也就是从最底层开始往上

【字符串处理+动规】单词的划分

[字符串处理+动规]单词的划分 Time Limit: 1000MS Memory Limit: 2560KB 有一个很长的由小写字母组成字符串.为了便于对这个字符串进行分析,需要将它划分成若干个部分,每个部分称为一个单词.出于减少分析量的目的,我们希望划分出的单词数越少越好.你就是来完成这一划分工作的. 输入格式 第一行,一个字符串.(字符串的长度不超过100)     第二行一个整数n,表示单词的个数.(n<=100)     第3~n+2行,每行列出一个单词. 输出格式     一个整数,

[ACM] hdu 1231 最大连续子序列 (动规复习)

最大连续子序列 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 17687    Accepted Submission(s): 7828 Problem Description 给定K个整数的序列{ N1, N2, ..., NK },其任意连续子序列可表示为{ Ni, Ni+1, ..., Nj },其中 1 <= i <= j