链接:

https://www.acwing.com/problem/content/285/

题意:

“多边形游戏”是一款单人益智游戏。

游戏开始时,给定玩家一个具有N个顶点N条边(编号1-N)的多边形,如图1所示,其中N = 4。

每个顶点上写有一个整数,每个边上标有一个运算符+(加号)或运算符*(乘号)。

1179_1.jpg

第一步,玩家选择一条边,将它删除。

接下来在进行N-1步,在每一步中,玩家选择一条边,把这条边以及该边连接的两个顶点用一个新的顶点代替,新顶点上的整数值等于删去的两个顶点上的数按照删去的边上标有的符号进行计算得到的结果。

下面是用图1给出的四边形进行游戏的全过程。

1179_2.jpg

最终,游戏仅剩一个顶点,顶点上的数值就是玩家的得分,上图玩家得分为0。

请计算对于给定的N边形,玩家最高能获得多少分,以及第一步有哪些策略可以使玩家获得最高得分。

思路:

先处理环, 将环变成链式再扩大两倍,就可以处理环了,从l-(l+n-1)的范围就是将l前面的边在第一步断开的情况.

考虑步数, 对两个堆进行dp, 操作受到符号限制.

代码:

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int INF = 1e9;
  4. const int NINF = -1e9;
  5. int a[110], op[110];
  6. int Dp[110][110][2];
  7. int n;
  8. char ope;
  9. int main()
  10. {
  11. scanf("%d", &n);
  12. getchar();
  13. for (int i = 1;i <= n;i++)
  14. {
  15. scanf("%c%d", &ope, &a[i]);
  16. getchar();
  17. // cout << ope << endl;
  18. if (ope == 't')
  19. op[i] = 1;
  20. else
  21. op[i] = 0;
  22. }
  23. for (int i = n+1;i <= 2*n;i++)
  24. {
  25. a[i] = a[i-n];
  26. op[i] = op[i-n];
  27. }
  28. for (int i = 1;i <= 2*n;i++)
  29. {
  30. for (int j = 1;j <= 2*n;j++)
  31. {
  32. Dp[i][j][0] = NINF, Dp[i][j][1] = INF;
  33. if (i == j)
  34. Dp[i][j][0] = Dp[i][j][1] = a[i];
  35. }
  36. }
  37. // for (int i = 1;i <= 2*n;i++)
  38. // cout << op[i] << ' ' << a[i] << ' ' ;
  39. // cout << endl;
  40. for (int len = 2;len <= n;len++)
  41. {
  42. for (int l = 1;l <= 2*n-len+1;l++)
  43. {
  44. int r = l+len-1;
  45. for (int k = l;k < r;k++)
  46. {
  47. if (op[k+1] == 1)
  48. {
  49. Dp[l][r][0] = max(Dp[l][r][0], Dp[l][k][0]+Dp[k+1][r][0]);
  50. Dp[l][r][1] = min(Dp[l][r][1], Dp[l][k][1]+Dp[k+1][r][1]);
  51. }
  52. else
  53. {
  54. Dp[l][r][0] = max(Dp[l][r][0], Dp[l][k][0]*Dp[k+1][r][0]);
  55. // Dp[l][r][0] = max(Dp[l][r][0], Dp[l][k][0]+Dp[k+1][r][0]);
  56. Dp[l][r][0] = max(Dp[l][r][0], Dp[l][k][1]*Dp[k+1][r][1]);
  57. Dp[l][r][0] = max(Dp[l][r][0], Dp[l][k][1]*Dp[k+1][r][0]);
  58. Dp[l][r][0] = max(Dp[l][r][0], Dp[l][k][0]*Dp[k+1][r][1]);
  59. Dp[l][r][1] = min(Dp[l][r][1], Dp[l][k][1]*Dp[k+1][r][1]);
  60. // Dp[l][r][1] = min(Dp[l][r][1], Dp[l][k][1]+Dp[k+1][r][1]);
  61. Dp[l][r][1] = min(Dp[l][r][1], Dp[l][k][0]*Dp[k+1][r][0]);
  62. Dp[l][r][1] = min(Dp[l][r][1], Dp[l][k][1]*Dp[k+1][r][0]);
  63. Dp[l][r][1] = min(Dp[l][r][1], Dp[l][k][0]*Dp[k+1][r][1]);
  64. }
  65. }
  66. }
  67. }
  68. int ans = NINF;
  69. for (int l = 1;l <= n+1;l++)
  70. {
  71. int r = l+n-1;
  72. // cout << Dp[l][r][0] << endl;
  73. ans = max(ans, Dp[l][r][0]);
  74. }
  75. set<int> st;
  76. for (int l = 1;l <= n;l++)
  77. {
  78. int r = l+n-1;
  79. if (Dp[l][r][0] == ans)
  80. st.insert(l);
  81. }
  82. printf("%d\n", ans);
  83. for (auto x: st)
  84. printf("%d ", x);
  85. puts("");
  86. return 0;
  87. }
  88. /*
  89. 3
  90. t 1 t 1 x 1
  91. */

Acwing-283-多边形(区间DP)的更多相关文章

  1. 多边形——————区间dp

    原题链接:https://www.acwing.com/problem/content/285/ 题意简单来说就是:给你一个环,断掉一条边使其成为一个链,用这个链跑dp,求最大得分. 首先这不是一道板 ...

  2. poj1179多边形——区间DP

    题目:http://poj.org/problem?id=1179 区间DP,值得注意的是有负值,而且有乘法,因此可能会影响最大值: 注意memset中写-1仅仅是-1,-2才是一个很小的负数: 最后 ...

  3. Hzoi 2018.2.11多边形 区间DP

    给定一个由N个顶点构成的多边形,每个顶点被赋予一个整数值,而每条边则被赋予一个符号:+(加法运算)或者*(乘法运算),所有边依次用整数1到N标识. 一个多边形的图形表示 首次移动,允许将某条边删除: ...

  4. Vijos 1565 多边形 【区间DP】

    描述 zgx给了你一个n边的多边形,这个多边形每个顶点赋予一个值,每条边都被标上运算符号+或*,对于这个多边形有一个游戏,游戏的步骤如下:(1)第一步,删掉一条边:(2)接下来n-1步,每步对剩下的边 ...

  5. 多边形游戏——区间dp

    题目描述 多边形(Polygon)游戏是单人玩的游戏,开始的时候给定一个由N个顶点构成的多边形(图1所示的例子中,N=4),每个顶点被赋予一个整数值,而每条边则被赋予一个符号:+(加法运算)或者*(乘 ...

  6. kuangbin 区间dp

    A - Cake 题目大意:给你一个n个顶点(n<=100)的多边形和每两个点连边的消耗,让你求把这个多边形全部切成三角形所需要的最小消耗,如果这个多边形为凹多边形则输出无解. 思路:先求一个凸 ...

  7. BZOJ 1719--[Usaco2006 Jan] Roping the Field 麦田巨画(几何&区间dp)

    1719: [Usaco2006 Jan] Roping the Field 麦田巨画 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 82  Solved ...

  8. 区间DP小结

    也写了好几天的区间DP了,这里稍微总结一下(感觉还是不怎么会啊!). 但是多多少少也有了点感悟: 一.在有了一点思路之后,一定要先确定好dp数组的含义,不要模糊不清地就去写状态转移方程. 二.还么想好 ...

  9. ZOJ 3537 Cake(凸包+区间DP)

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3537 题目大意:给出一些点表示多边形顶点的位置,如果不是凸多边形 ...

  10. ZOJ 3537 Cake 求凸包 区间DP

    题意:给出一些点表示多边形顶点的位置(如果多边形是凹多边形就不能切),切多边形时每次只能在顶点和顶点间切,每切一次都有相应的代价.现在已经给出计算代价的公式,问把多边形切成最多个不相交三角形的最小代价 ...

随机推荐

  1. ubuntu 编译安装 svn

    1,简单的安装svn (1)  sudo apt-get install subversion 但是此种方式,可能不能安装到当前最新的svn.如当前最新的版本是svn 1.8.9 ,但是 通过此种安装 ...

  2. android webview 添加内置对象

    package com.android.EBrowser; import android.app.Activity;import android.graphics.Rect;import androi ...

  3. netcore程序部署 docker 异常 --生成图片二维码缺少libdl

    最近因业务需求需要在程序中实现二维码图片生成,于是就用到QRCoder开发库.最终在windows环境下部署运行没问题,但切换到docker(centos7.0)后发现是有问题的. 错误信息提示:Th ...

  4. Linux CentOS安装搭建FTP文件服务

    本文环境:centos7,IP=192.168.1.11 1.安装vsftpd和默认配置启动 1.1 安装vsftpd yum install -y vsftpd 1.2 启动vsftpd syste ...

  5. finereport 填报 单元格 JS 触发 提交SQL 事件

    var location = this.options.location; var cr = FR.cellStr2ColumnRow(location); var col = cr.col; var ...

  6. 好用的 Chrome 插件

    这些好用的 Chrome 插件,提升你的工作效率   本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可 ...

  7. 小菜鸟之java JDBC编程

    JDBC技术 百度简介 :  JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一 ...

  8. mapreduce运行的bug收录

    在8088端口可以看到日志文件(主要看error),操作如下: 1.window jdk版本最好和linux jdk 版本一致,不然容易出现莫名奇妙的bug 之前出现一个bug: Unsupporte ...

  9. SpringBoot中使用Websocket进行消息推送

    WebsocketConfig.java @Configuration public class WebSocketConfig { @Bean public ServerEndpointExport ...

  10. vscode中eslint插件的配置-prettier

    用vue-cli构建vue项目,会有个eslint代码检测的安装 可vscode自带代码格式化是prettier格式(右键有格式化文件或alt+shift+f) 这时候要在vscode上装一个esli ...