题意:多边形游戏是一个单人玩的游戏,开始时有一个由n个顶点构成的多边形。每个顶点被赋予一个整数值,每条边被赋予一个运算符“+”或“*”。所有边依次用整数从1到n编号
游戏第1步,将一条边删除
随后n-1步按以下方式操作
(1)选择一条边E以及由E连接着的2个顶点V1和V2
(2)用一个新的顶点取代边E以及由E连接着的2个顶点V1和V2。将由顶点V1和V2的整数值通过边E上的运算得到的结果赋予新顶点
最后,所有边都被删除,游戏结束。游戏的得分就是所剩顶点上的整数值;
这道题很有意思,也比较有难度,是一个算式形式的动态规划,和区间dp还是有一定联系的,因为我们每次开始游戏时需要断开一条边,之后就变成了一条链,可以看做区间,这样,我们初步应该会想到f[l][r]来表示l到r合并后最大的价值。
!!但是,这样就会有一个非常谜的问题!最大值不仅是由最大值加和而来的,它还可能是由两个最小值乘来的(负负得正),这样题就没法做了,所以这个子问题不满足无后效性!只能另寻它法!虽然说这个子问题不合适,但是这离我们的正解也已经非常近了。
我们可以用f[l][r]表示l到r所能合成的最大值,然后f1[l][r]表示l到r能合成的最小值。为什么这就能满足无后效性呢,因为啊:
1.一个最大值无非就是由两个最大值相加,两个最大值相乘或者两个最小值相乘而得来的!
2.一个最小值无非就是由两个最小值相加,或两个最小值相乘,或前一个最小值和后一个最大值相乘,或后一个最小值和前一个最大值相乘而得来的!
所以,我们就能够依据上述关系写出状态转移方程,这里就不给出了;
这样呢,我们就能够用区间dp的套路安排循环!但是有一个巨大的问题,我们需要枚举首先断掉那条边!这样下来会很麻烦,怎么办呢。在处理动态规划的环形问题时,我们可以先把这个环断掉,从任意位置断掉,然后长度复制一条一模一样的链连接在其后,这样我们就可以通过区间的移动来达成首先断一条边的操作;因为区间每次向右移动一位,都代表着把原来断的那条边接上,在把现有的最左边这条边断掉!这样就能达成一个。枚举先断哪条边的作用!
于是这道题完美解决,下面看代码!

 1 //怕你飞远去
 2 //怕你离我而去
 3 //更怕你永远停留在这里
 4 #include<iostream>
 5 #include<cstdio>
 6 #include<cstdlib>
 7 #include<cstring>
 8 #include<string>
 9 #include<cmath>
10 #include<algorithm>
11 #include<queue>
12 using namespace std;
13 const int MAXN=125;
14 int f[MAXN][MAXN],f1[MAXN][MAXN],a[MAXN],n;//f[l][r]代表区间l到r所能合成的最大值,f1[l][r]表示区间l到r所能合成的最小值;
15 char b[MAXN];
16 int main()
17 {
18     scanf("%d",&n);
19     memset(f,-0x3f,sizeof(f));//初始化;
20     memset(f1,0x3f,sizeof(f1));//初始化;
21     for(int i=1;i<=n;i++){
22         getchar();
23         scanf("%c%d",&b[i],&a[i]);
24         b[i+n]=b[i];a[i+n]=a[i];//断开,复制成一个两倍长度的链;
25     }
26     for(int i=1;i<=2*n;i++){
27         f1[i][i]=f[i][i]=a[i];//初始化;
28     }//区间Dp
29     for(int i=2;i<=n;i++){//阶段(区间的长度)
30         for(int l=1;l<=n*2-i+1;l++){//状态(左端点)
31             int r=l+i-1;//状态(右端点)
32             for(int k=l;k<r;k++){//决策(嗯)
33                 if(b[k+1]=='t'){
34                     f[l][r]=max(f[l][r],f[l][k]+f[k+1][r]);//最大值由两个最大值相加而来
35                     f1[l][r]=min(f1[l][r],f1[l][k]+f1[k+1][r]);//最小值由两个最小值相加而来
36                 }
37                 else{
38                     f[l][r]=max(f[l][r],f[l][k]*f[k+1][r]);//最大值由两个最大值相乘而来
39                     f[l][r]=max(f[l][r],f1[l][k]*f1[k+1][r]);//最大值由两个最小值相乘而来
40                     f1[l][r]=min(f1[l][r],f1[l][k]*f1[k+1][r]);//最小值由两个最小值相乘而来
41                     f1[l][r]=min(f1[l][r],f[l][k]*f1[k+1][r]);//最小值由前一个最大值和后一个最小值相乘而来
42                     f1[l][r]=min(f1[l][r],f1[l][k]*f[k+1][r]);//最小值由前一个最小值和后一个最大值相乘而来;
43                 }
44             }
45         }
46     }
47     int maxx=-0x7fffffff;
48     for(int i=1;i<=n;i++){
49         maxx=max(maxx,f[i][i+n-1]);
50     }
51     printf("%d",maxx);
52     puts("");
53     for(int i=1;i<=n;i++){
54         if(f[i][n-1+i]==maxx){//枚举,寻找第一步最优策略,有几个输出几个!
55             printf("%d ",i);
56         }
57     }
58     puts("");
59     return 0;
60 }

View Code

转载于:https://www.cnblogs.com/Alan-Luo/articles/8723289.html

POJ1179 Polygon 【例题精讲】相关推荐

  1. l2-004 这是二叉搜索树吗?_LeetCode 例题精讲 | 11 二叉树转化为链表:二叉树遍历中的相邻结点...

    本期例题: LeetCode 98. Validate Binary Search Tree 验证二叉搜索树(Medium) LeetCode 426. Convert Binary Tree to ...

  2. led伏安特性实验误差分析_高中物理 | 电学实验满分知识点总结+拓展+例题精讲,罕见的好资料,收藏不亏!...

    在物理的学习过程中,电学实验是必考题,很多同学是"遇到就怕".而物理又是高中比较重要的学科,电学是物理一个重要的知识点,所以要想学好物理,电学部分就必须掌握好. 在高中的物理学习中 ...

  3. acm新手小白必看系列之(5)——枚举进阶例题精讲

    acm新手小白必看系列之(5)--枚举进阶例题精讲 1.牛奶碑文(暴力枚举) 小伟暑假期间到大草原旅游,在一块石头上发现了一些有趣的碑文.碑文似乎是一个神秘古老的语言,只包括三个大写字母 C.O 和 ...

  4. 数字电路实验怎么接线视频讲解_【高中物理】电学实验满分知识点总结及例题精讲...

    电学实验最全知识点总结 一.实验的考查内容 (1)测定金属的电阻率(练习使用螺旋测微器): (2)描绘小灯泡的伏安特性曲线: (3)测定电源的电动势和内阻: (4)练习使用多用电表: (5)传感器的简 ...

  5. c++链表形参丢失_LeetCode 例题精讲 | 01 反转链表:如何轻松重构链表

    本期例题:LeetCode 206 - Reverse Linked List(Easy) 反转一个单链表.示例: 输入: 1->2->3->4->5->NULL 输出: ...

  6. LeetCode 例题精讲 | 08 排列组合问题:回溯法的候选集合

    点击关注上方"五分钟学算法", 设为"置顶或星标",第一时间送达干货. 转自面向大象编程 本期例题:LeetCode 46 - Permutations[1]( ...

  7. LeetCode 例题精讲 | 05 双指针×链表问题:快慢指针

    点击关注上方"五分钟学算法", 设为"置顶或星标",第一时间送达干货. 转自面向大象编程 本期例题: LeetCode 876 - Middle of the ...

  8. 弹性碰撞后速度方向_高中物理竞赛典型例题精讲——垫圈弹性碰撞后速度方向...

    04-07-16_垫圈弹性碰撞后速度方向 本期高中物理竞赛试题,我们来看一下非对心正碰情况下的物体运动状态,并且考虑在题目中给出的特殊情况下的物体运动状态的控制方法,其实对于碰撞以后的物体的运动状态的 ...

  9. python弹性碰撞次数圆周率_高中物理竞赛典型例题精讲——盒内滑块弹性碰撞次数...

    04-07-08_盒内滑块弹性碰撞次数 本期高中物理竞赛试题,我们共同来研究一下弹性碰撞过程与摩擦阻力作用下的运动相结合的题目的解题思路和方法,从这里也就能够明确,本期题目的主要考查重点在两个位置,其 ...

最新文章

  1. 如何使用Salt 的各种状态值
  2. input的表单验证(不断更新中~~)
  3. JS基础--函数与BOM、DOM操作、JS中的事件以及内置对象
  4. leetcode714.买卖股票的
  5. 你被限流了吗?| 图解+代码
  6. 右键新建里面没有word和excel_Excel中为什么修改了新建工作簿的选项,新建以后还是没有生效...
  7. tinymce 字体样式_TinyMCE-添加中文字体及修改字体大小
  8. 伪静态 全站php 跳到html,IIS下万能301跳转方法:URL伪静态重写+PHP301
  9. 宝塔linux怎么运行war,宝塔Linux面板在线解压WAR压缩文件
  10. 计算机开机错误0xc0000428,启动时出现错误码0xc0000428如何解决?
  11. python:游戏倒计时器
  12. 如何使用NFC读卡器读取NFC卡片的UID
  13. word使用技巧---插入图片显示不全的解决方案
  14. 手把手教你做短视频去水印微信小程序(2-首页)
  15. 专利权利要求书七步法
  16. 计算机网络胡工程施工税率,弱电项目增值税6%、9%、13%税率怎样区分?项目经理必知...
  17. 解析联想AI实践:数字化让CIO职责发生了变化,而我们有数据中心
  18. MySQL最佳基友之PHP入坑指南—白俊遥
  19. 题目4:常微分方程初值问题
  20. ubuntu 18共享文件夹不显示问题解决

热门文章

  1. 字符流缓冲区的使用之BufferedWriter和BufferedReader
  2. eclipse插件大全整理学习
  3. 【刷算法】字符串的全排列
  4. 使用zerorpc踩的第一个坑:
  5. Oracle DBA课程系列笔记(16)
  6. Maven:基本使用
  7. 通过VB向SQL Server数据库中录入数据
  8. 在Linux中创建静态库.a和动态库.so
  9. 读书笔记《集体智慧编程》Chapter 5 : Optimization
  10. Something about WinCE6.0 R3