1)问题描述

多边形游戏是一个单人玩的游戏,开始时有一个由n个顶点构成的多边形。每个顶点被赋予一个整数值,每条边被赋予一个运算符+或*。所有边依次用整数从1到n编号,游戏第1步,将一条边删除。
随后n-1步按以下方式操作:
(1)选择一条边E以及由E连接着的两个顶点V1和V2;
(2)用一个新的顶点取代边E以及由E连接着的两个顶点V1和V2。将由顶点V1和V2 的整数值通过边E上的运算得到的结果赋予新顶点。
最后,所有边都被删除(断开),游戏结束。游戏的得分就是所剩顶点上的整数值。问题:对于给定的多边形,计算最高分。

2)代码实现

package hello;
import java.util.HashMap;
import java.util.Scanner;
import java.util.Stack;public class fuck {private int n; //多边形边数private char[] op; //每条边的对应的操作(从1开始计数)private int[] v; //每个顶点数值(从1开始计数)private long[][][] m; //m[i][n][1]:代表一开始删除第i条边,长度为n的链(包含n个顶点),所能得到的最大值//m[i][n][0]:代表一开始删除第i条边,长度为n的链,所能得到的最小值private int[][][] cut; //cut[i][j][0];表示m[i][j][0]这条链的达到最小数值的时候断开的位置//cut[i][j][1]: 表示m[i][j][1]这条链的达到最大数值的时候断开的位置private Stack<Integer> stack; //用栈保存合并边的顺序private int firstDelEdge; //记录最优情况下,第1条删除的边private long bestScore; //记录最优得分//初始化public fuck(int n, long[][][] m, char[] op, int[] v){     this.n = n;this.m = m;this.op = op;this.v = v;this.cut = new int[n+1][n+1][2];this.stack = new Stack<>();}//************************************************************************************************************************************/*** 子函数* 服务于主执行函数,就是主函数的一些方法的封装*///把断开的边是*还是+的时候计算最大值和最小值封装在一起,向外暴露一个统一的方法private HashMap<String, Long> minMax(int i, int s, int j, HashMap<String, Long> resMap){    int r = (i+s-1) % n + 1;long a = m[i][s][0], b = m[i][s][1], c = m[r][j-s][0], d = m[r][j-s][1];if(op[r] == '+'){resMap.put("minf", a+c);resMap.put("maxf", b+d);}else{long[] e = new long[]{0, a*c, a*d, b*c, b*d};long minf = e[1], maxf = e[1];for (int k = 2; k < 5; k++){if(minf > e[k]) minf = e[k];if(maxf < e[k]) maxf = e[k];}resMap.put("minf", minf);resMap.put("maxf", maxf);}return resMap;}/*** 获取最优的合并序列,存入stack中* @param i 表示子链从哪个顶点开始* @param j 子链的长度(如j=2,表示链中有两个顶点)* @param needMax 是否取链的最大值,如果传入值为false,则取子链的最小值*///算出子链m[i][j][1(0)]取到最大(小)值的时候要断开的点,并压栈,在需要的时候出栈。//递归压栈到子链的长度为1(即j为1的时候)。private void getBestSolution(int i, int j, boolean needMax){//needMax为true的话就是把要取子链的最大值的时候断开的点压栈,为false就是把要取子链的最小值的时候断开的点压栈int s,r;if(j == 1){  //链中只有一个顶点,直接返回          }else if(j == 2){s = cut[i][j][1];r = (i+s-1) % n + 1;    //因为压栈的r是相对于最开始的,而s是相对于i的。stack.push(r);}else {      //链中有两个以上的顶点时,将最优的边入栈        s = needMax ? cut[i][j][1] : cut[i][j][0];      r = (i+s-1) % n + 1;stack.push(r);//当j>2的时候的递归操作if(this.op[r] == '+'){                                   //当合并计算为"+"操作时if(needMax){ //如果合并得到的父链需要取得最大值getBestSolution(i, s, true);getBestSolution(r, j-s, true);}else { //如果合并得到的父链需要取得最小值getBestSolution(i, s, false);getBestSolution(r, j-s, false);}}else{                                                      //当合并计算为"*"操作时long a = m[i][s][0], b = m[i][s][1], c = m[r][j-s][0], d = m[r][j-s][1];long[] e = new long[]{0, a*c, a*d, b*c, b*d};long mergeMax = e[1], mergeMin = e[1];for(int k=2; k<=4; k++){if(e[k] > mergeMax) mergeMax = e[k];if(e[k] < mergeMin) mergeMin = e[k];}long merge = ((needMax) ? mergeMax : mergeMin);   //判断合并得到的父链是取最大还是取最小if(merge == e[1]){ //子链1和子链2都取最小getBestSolution(i, s, false);getBestSolution(r, j-s, false);}else if(merge == e[2]){ //子链1取最小,子链2取最大getBestSolution(i, s, false);getBestSolution(r, j-s, true);}else if(merge == e[3]){ //子链1取最大,子链2取最小getBestSolution(i, s, true);getBestSolution(r, j-s, false);}else { //子链1和子链2都取最大getBestSolution(i, s, true);getBestSolution(r, j-s, true);}}}}//************************************************************************************************************************************   /*** 主执行函数* 就是主要的算法的核心*///算出断开哪个的点的时候最值并把最值填入m[i][j][0] 和 m[i][j][1];把断开的点填入cut[i][j][0]和cut[i][j][1]private void polyMax(){//1 填表 m[i][j][0] 和 m[i][j][1] 和 cut[i][j][0] 和 cut[i][j][1]HashMap<String, Long> resMap = new HashMap<>();for (int j = 2; j <= n; j++){            //链的长度for(int i = 1; i<= n; i++){          //一开始断开第i条边的时候m[i][j][0] = Long.MAX_VALUE;m[i][j][1] = Long.MIN_VALUE;for(int s = 1; s < j; s++){      //断开的位置resMap = this.minMax(i, s, j, resMap);if(m[i][j][0] > resMap.get("minf")){m[i][j][0] = resMap.get("minf");cut[i][j][0] = s; //记录该链取得最小值的断点}if(m[i][j][1] < resMap.get("maxf")){m[i][j][1] = resMap.get("maxf");cut[i][j][1] = s; //记录该链取得最大值的断点}}}}//2 根据表m算出第一次断开哪里的时候的数值最大,并输出一些相关数据bestScore = m[1][n][1];firstDelEdge = 1; //一开始断开的边,初始化为第一条边for (int i = 2; i <= n; i++){if(bestScore < m[i][n][1]){bestScore = m[i][n][1];firstDelEdge = i; //如果一开始断开第i边有更优的结果,则更新}}System.out.print("\n");System.out.println("一开始断开第i条边时可以形成的最大数值:");for(int i=1; i<=n; i++){ //一开始断开第i条边所能得到的最大分数System.out.println("i=" + i + " " + m[i][n][1]);}System.out.print("\n");System.out.println("【第一次应该断开的边为:firstDelEdge=" + firstDelEdge+"】");//3 利用getBestSolution方法算出达到最大数值的时候的断开顺序并输出System.out.print("\n");getBestSolution(firstDelEdge, n, true);   //把子链m[firstDelEdge][n]要取最大值的时候要断开的点依次压栈。 System.out.println("要想得到最大的数断开的顺序为:");System.out.println("stack--> "+ firstDelEdge);while (!stack.empty()){ //打印在断开第firstDelEdge条边后的最优合并顺序System.out.println("stack--> " + String.valueOf(stack.pop()));}System.out.print("\n");System.out.println("【按以上断开顺序后得到的数(最大的数值)为:BestScore=" + bestScore+"】"); }//************************************************************************************************************************************   /*** 主函数* @param args*/public static void main(String[] args){System.out.println("请输入你要输入的边(点)的个数:");Scanner scanner = new Scanner(System.in);while(scanner.hasNext()){//1 输入流int n = scanner.nextInt();long[][][] m = new long[n+1][n+1][2];char[] op = new char[n+1];int[] v = new int[n+1];System.out.print("\n");System.out.println("请输入边和点:");for(int i=1; i<=n; i++){    //i从1开始op[i] = scanner.next().charAt(0);v[i] = scanner.nextInt();}//2 初始化fuck ploygonAgent = new fuck(n, m, op, v);for (int i=1; i<=n; i++){                           //初始化m[i][j][0]和m[i][j][1]的第一列m[i][1][0] = m[i][1][1] = v[i];}//3 主执行函数ploygonAgent.polyMax();}scanner.close();}
}
请输入你要输入的边(点)的个数:
5请输入边和点:
* -5 + -2 * -8 * -5 + 8一开始断开第i条边时可以形成的最大数值:
i=1 168
i=2 480
i=3 488
i=4 488
i=5 120【第一次应该断开的边为:firstDelEdge=3】要想得到最大的数断开的顺序为:
stack--> 3
stack--> 2
stack--> 1
stack--> 5
stack--> 4【按以上断开顺序后得到的数(最大的数值)为:BestScore=488】

3)时间复杂度和空间复杂度

时间复杂度:

O(n*3)
【主要的时间复杂度就在于那填表的三个for】

空间复杂度:

O(n*2)

动态规划--多边形游戏相关推荐

  1. 动态规划-多边形游戏算法

    动态规划-多边形游戏算法 一.多边形游戏简介 首先,多边形游戏是一个单人玩的游戏. 游戏初始时是由n(n>=3)个顶点构成的多边形,每个顶点被赋予一个整数值,每条边被赋予一个运算符"+ ...

  2. 动态规划---多边形游戏

    1.问题描述: 给定N个顶点的多边形,每个顶点标有一个整数,每条边上标有+(加)或是×(乘)号,并且N条边按照顺时针 依次编号为1~N.下图给出了一个N=4个顶点的多边形. 游戏规则 :(1) 首先, ...

  3. 动态规划多边形游戏c语言,动态规划-多边形游戏问题

    1.描述:有一个由n个顶点构成的多边形.每个顶点被赋予一个整数值,每条边被赋予一个运算符"+"或"*".所有边依次用整数从1到n编号. 游戏第1步,将一条边删除 ...

  4. java实现多边形游戏问题_动态规划-多边形游戏

    算法思想:动态规划 实际问题:多边形游戏 编写语言:Java 前言 多边形游戏问题是矩阵连乘的最优计算次序问题与凸多边形最优三角剖分问题的推广.我在解决凸多边形最优三角剖分问题时偶然间看到了这个结论, ...

  5. 萌新做点小玩意儿DAY-4 动态规划解决多边形游戏

    还是先简单的介绍一下动态规划的算法思想,跟分治法的思想相似的是把一个比较大的问题分解成若干子问题,而分治法分解出来的子问题都是相同规模有相同的解决办法的,动态规划可以通过空间换时间来解决这些相同的问题 ...

  6. 多边形游戏-动态规划(Java)

    问题说明 开始时一个由n个顶点构成的多边形.每个顶点被赋予一个整数值,每条边被赋予一个运算符"+"或" × ".所有边依次用整数从1到n编号.之后,将相邻两个顶 ...

  7. 多边形游戏(动态规划)

    多边形游戏(动态规划) 理论和解题步骤有两位大佬说的很好,我就不卖弄了,直接贴他们的,我注释课本中的代码是什么意思. 理论支持--点这里 超超超超级详细解题步骤--点这里 #include <i ...

  8. 动态规划---例题6.多边形游戏

    一.题目描述 多边形游戏是一个单人玩的游戏,开始时有一个由n个顶点构成的多边形.每个顶点被赋予一个整数值,每条边被赋予一个运算符"+"或"*".所有边依次用整数 ...

  9. 超超超超级详细的多边形游戏问题分析(动态规划)

    多边形游戏 问题简介 问题分析 超详细解题步骤 Java代码实现 多边形游戏 问题简介 首先呢,介绍一下多边形游戏是个什么东东 多边形游戏是一个单人玩的游戏,开始时有一个由n个顶点构成的多边形.每个顶 ...

最新文章

  1. Java设计模式之虚拟代理模式
  2. 用 Flask 来写个轻博客 (21) — 结合 reCAPTCHA 验证码实现用户注册与登录
  3. 处理数字_10_计算某列重复最多的值
  4. 第三方软件源_手机上的天气软件哪个更准确?
  5. 东北天到ecef的变换_GNSS学习笔记-坐标转换
  6. android 图片叠加xml,Android实现图片叠加效果的两种方法
  7. sed查找文件包含字段_sed(查找替换) 与awk(提取字段)
  8. python sklearn svm 权重_sklearn svm基本使用
  9. 一维搜索——进退法matlab实现(含代码)
  10. 无法远程连接 mysql(Ubuntu)
  11. 运动控制器位置锁存功能的应用
  12. linux系统usb触摸驱动,Linux ——usb触摸屏驱动 - usbtouchscreen
  13. 佰落暑期java自学记录-9
  14. python 文本框不能放表情_用Python自动生成表情包,生活不易多才多艺!
  15. 海思开发板设置开机自启动方法
  16. ORA-29702错误解决
  17. ESP32-Arduino开发实例-与Arduino之间SPI通信
  18. An internal routine has requested a dump of selected redo.This usually happens following a specific
  19. 【转】校园招聘 建议
  20. hdu6112 今夕何夕

热门文章

  1. 使用阿里矢量图标的三种方法
  2. Hankson的趣味题
  3. 【POJ3208】Apocalypse Someday
  4. WPF 中Combox的使用
  5. 多么痛的领悟!——我的2013拾遗总结
  6. 基于CSMA/CA无线传感器网络的MAC层研究
  7. 这几款免费的思维导图软件你或许没用过,快来试试吧
  8. 武汉疫情之后对行业影响及思考
  9. 性能测试数据准备-埋数篇
  10. Python爬虫帮你抢秒杀