问题描述


思路

  刚拿到题目的时候感觉是一脸懵的,道理我都懂,但是思路和头绪倒是一直没有蹦出来,妥妥的一个模拟类题的茫然脸。
  第一个思路肯定是暴力穷举,当然这种办法比较low,而且很可能在时空复杂度上爆掉,所以直接扔掉。
  首先尝试手动模拟流程,寻找规律,主要从 + * 的顺序入手,观察数字对它们的影响。由于负数的存在,分类讨论难度过于繁复,先放一边,其他思路不可以再用它推进。
  因为是个最优解问题,很自然地想到局部最优推得全局最优,因此萌生了动态规划计算最优子结构的办法。

动态规划

  那么问题来了,既然是动态规划计算最优子结构,那怎样算最优子结构呢?不同于其他问题直接取最大值为最优子结构,因为这个问题存在乘法负负得正的情况,因此我们还需要考虑取添加分类讨论过程,将乘法时左右两边都为负列入考虑范围。
  考虑了最优子结构的定义,剩下的就是递归求解的过程了。我们知道动态规划中有两个非常重要的概念——状态转移方程和临界条件。我们从合并的角度考虑问题:
  +:
    min_now = minl + minr
    max_now = maxl + maxr
  *:
    min_now = min(minl * minr, maxl * maxr, minl * maxr, minr * maxl)
    max_now = max(minl * minr, maxl * maxr, minl * maxr, minr * maxl)
  式中,minl,maxl为合并前符号左边的最小值与最大值;minr,maxr为合并前符号右边的最小值与最大值。因为考虑到正负号的问题,所以*部分需要对四种情况讨论。
  个人认为这个思路还是穷举的味道比较重的。

代码

#include<bits/stdc++.h>
using namespace std;
int get_minmax(int left, int point, int len);int n;
// 用了递归,数据不可能太大的,因为缓冲区会炸
// max[i][j]从第i位开始,往后数j个数(包括第i个数),j是链子的长度
int max_num[1000][1000], min_num[1000][1000];
char op[1000];int get_minmax(int left, int point, int len){int min_now, max_now;                // 断在s时合起来的最大最小 int real_point = (left+point)%n;      // 因为是个圆,这意味这断real_point边 int minleft = min_num[left][point];      // 因为point<len,所以这里的区间都是被计算过的 int maxleft = max_num[left][point];int minright = min_num[real_point][len-point];int maxright = max_num[real_point][len-point];// 计算s点合并掉后新的点的最大值最小值 if(op[real_point] == '+'){min_now = minleft+minright;max_now = maxleft+maxright; }else{min_now = min(minleft*minright, min(minleft*maxright, min(maxleft*minright, maxleft*maxright)));max_now = max(minleft*minright, max(minleft*maxright, max(maxleft*minright, maxleft*maxright)));}return min_now, max_now;
} int main(){scanf("%d", &n);char jump;scanf("%c", &jump); for (int i = 0; i<n; i++){scanf("%c", &op[i]);int temp;scanf("%d", &temp);max_num[i][1] = temp;   // 初始化 min_num[i][1] = temp;}for (int i = 0;i<n;i++){printf("%d ",max_num[i][1]);}printf("\n");int min_now,max_now;          // 代表[i,j]中能出的最大值最小值 // 第一重对应不同长度下两边的最优解。因此到了n就是最终结果for(int j=2; j<=n; j++)          // 因为j=1已经在之前确定完了,长度为1的时候就是自己。// 第二重对应不同起点下不同长度的最优解,就是区间[i,i+j-1]的里的最优解for(int i=0;i<n;i++)       // 要干掉第i个点  // 第三重就是在这个区间中找到断点的最佳位置for(int s=1; s<=j-1; s++){    // s是对应[i,i+j]中间的第s个数 min_now, max_now = get_minmax(i, s, j);max_num[i][j] = max(max_num[i][j], max_now);min_num[i][j] = min(min_num[i][j], min_now);}int ret = max_num[0][n];
//  for(int i = 0; i<n; i++){//      ret = max(ret, max_num[i][n]);
//      for (int j=1;j<=n;j++)
//          printf("%d ", max_num[i][j]);
//      printf("\n");
//  }           printf("%d", ret);return 0;
}
//测试数据:
//4
//+-7+4*2*5

  三重for循环中的前两重的顺序是个细节操作,不可以换位置,因为换位之后会造成计算时用到了没被处理的max_num和min_num,比如计算max_num[0][3]时,当point为1,则max_num=max_num[0][1]+max_num[1][2],此时因为大循环是首个空断边,所以才进行到0,max_num[1][2]还没被计算到,所以仍为0。

  黄色背景的是被计算过的数据,红色字体的是正在计算的数据,绿色字体的是此时计算所要用到的数据。我们可以发现先循环长度才能保证每次被用到的数据的断点长度point<已有长度len,同时用到的数据max_num[real_point][len-point]也被计算完了。如下图:

多边形游戏 动态规划C语言实现相关推荐

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    1)问题描述 多边形游戏是一个单人玩的游戏,开始时有一个由n个顶点构成的多边形.每个顶点被赋予一个整数值,每条边被赋予一个运算符+或*.所有边依次用整数从1到n编号,游戏第1步,将一条边删除. 随后n ...

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

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

最新文章

  1. 【PHPExcel】数学公式
  2. visual basic6.0企业版
  3. Laravel 学习开篇
  4. 【Python】趣学Python变量和赋值:大师兄和二师兄教的好~
  5. MADDPG中环境怎么配置,multiagent包解决
  6. iFixit:手机屏幕底部安装小芯片致第三方维修iPhone 13屏幕更难
  7. python反向代理服务器_主机、服务器,代理服务器,反向代理服务器理解(自用)...
  8. 用Delphi中的Indy控件实现收发邮件
  9. java final 变量 大小写_java – 为什么“final static int”可以用作开关的大小写常量但不是“final static”...
  10. A network analyzer is used for
  11. java毕业设计校园博客系统mybatis+源码+调试部署+系统+数据库+lw
  12. 网络空间安全和计算机软件,网络空间安全
  13. netty权威指南学习
  14. Android 阿里云推送集成指南
  15. 计算机专业实践报告立题依据,开题报告立题依据 .doc
  16. 责任心与态度比技术更重要
  17. 小说作者推荐:没有颜色的无合集
  18. Runtime.getRuntime().availableProcessors()
  19. 2020(第十六届)北京汽车展览会-以Tesla为参考标的分析
  20. Vue源码实现之watcher拾遗

热门文章

  1. win10专业版 Virtualbox-Ubuntu 开机黑屏解决办法
  2. Linux Suse 11系统下的NFS配置
  3. 收集到的手机应用商城的地址
  4. 数据库新增幂等操作_数据库幂等性
  5. SQL复制表数据到另一张表
  6. 卡尔曼滤波-Simulink仿真
  7. 讨论一下,乌云漏洞库的学习方法
  8. 《我的心曾悲伤七次》----卡里·纪伯伦
  9. date-fns 月助手函数
  10. 自动(智能)驾驶 | 时间同步之给工控机授时(PPS+GPRMC)