链接:

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, 操作受到符号限制.

代码:

#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9;
const int NINF = -1e9; int a[110], op[110];
int Dp[110][110][2];
int n;
char ope; int main()
{
scanf("%d", &n);
getchar();
for (int i = 1;i <= n;i++)
{
scanf("%c%d", &ope, &a[i]);
getchar();
// cout << ope << endl;
if (ope == 't')
op[i] = 1;
else
op[i] = 0;
}
for (int i = n+1;i <= 2*n;i++)
{
a[i] = a[i-n];
op[i] = op[i-n];
}
for (int i = 1;i <= 2*n;i++)
{
for (int j = 1;j <= 2*n;j++)
{
Dp[i][j][0] = NINF, Dp[i][j][1] = INF;
if (i == j)
Dp[i][j][0] = Dp[i][j][1] = a[i];
}
}
// for (int i = 1;i <= 2*n;i++)
// cout << op[i] << ' ' << a[i] << ' ' ;
// cout << endl;
for (int len = 2;len <= n;len++)
{
for (int l = 1;l <= 2*n-len+1;l++)
{
int r = l+len-1;
for (int k = l;k < r;k++)
{
if (op[k+1] == 1)
{
Dp[l][r][0] = max(Dp[l][r][0], Dp[l][k][0]+Dp[k+1][r][0]);
Dp[l][r][1] = min(Dp[l][r][1], Dp[l][k][1]+Dp[k+1][r][1]);
}
else
{
Dp[l][r][0] = max(Dp[l][r][0], Dp[l][k][0]*Dp[k+1][r][0]);
// Dp[l][r][0] = max(Dp[l][r][0], Dp[l][k][0]+Dp[k+1][r][0]);
Dp[l][r][0] = max(Dp[l][r][0], Dp[l][k][1]*Dp[k+1][r][1]);
Dp[l][r][0] = max(Dp[l][r][0], Dp[l][k][1]*Dp[k+1][r][0]);
Dp[l][r][0] = max(Dp[l][r][0], Dp[l][k][0]*Dp[k+1][r][1]); Dp[l][r][1] = min(Dp[l][r][1], Dp[l][k][1]*Dp[k+1][r][1]);
// Dp[l][r][1] = min(Dp[l][r][1], Dp[l][k][1]+Dp[k+1][r][1]);
Dp[l][r][1] = min(Dp[l][r][1], Dp[l][k][0]*Dp[k+1][r][0]);
Dp[l][r][1] = min(Dp[l][r][1], Dp[l][k][1]*Dp[k+1][r][0]);
Dp[l][r][1] = min(Dp[l][r][1], Dp[l][k][0]*Dp[k+1][r][1]);
}
}
}
}
int ans = NINF;
for (int l = 1;l <= n+1;l++)
{
int r = l+n-1;
// cout << Dp[l][r][0] << endl;
ans = max(ans, Dp[l][r][0]);
}
set<int> st;
for (int l = 1;l <= n;l++)
{
int r = l+n-1;
if (Dp[l][r][0] == ans)
st.insert(l);
}
printf("%d\n", ans);
for (auto x: st)
printf("%d ", x);
puts(""); return 0;
}
/*
3
t 1 t 1 x 1
*/

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. C++中map和unordered_map的用法

    1. 简介 map和unordered_map都是c++中可以充当字典(key-value)来用的数据类型,但是其基本实现是不一样的. 2. map 对于map的底层原理,是通过红黑树(一种非严格意义 ...

  2. springboot 部署jar项目与自启动

    1.项目路径 jar包路径:/usr/local/src/apps/govdata.jar 2.启动项目 nohup java -jar govdata.jar & 3.查看项目启动日志 ta ...

  3. [HAOI2016]字符合并

    Luogu3736 很容易想到直接DP,关键是枚举顺序. \(1.\)设后一段构成最后一个点,前一段构成前面的点,那么能得到\(1\)个点的数量要求 : \(1,k,2k-1...\)相差\(k-1\ ...

  4. [BZOJ 2002] [HNOI2010]弹飞绵羊(Link Cut Tree)

    [BZOJ 2002] [HNOI2010]弹飞绵羊(Link Cut Tree) 题面 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一 ...

  5. c++学习笔记之类和对象(一、类定义)

    类和对象是 C++ 的重要特性,它们使得 C++ 成为面向对象的编程语言. 类是创建对象的模板,一个类可以创建多个对象,每个对象都是类类型的一个变量:创建对象的过程也叫类的实例化.每个对象都是类的一个 ...

  6. pwd命令和修改PS1环境变量在bash行的显示

    一.pwd:显示当前所在的位置 语法 pwd [选项] ... 描述       打印当前工作目录的完整文件名. -L,--logical              从环境使用PWD,即使它包含符号链 ...

  7. SpringMVC实现全局异常处理器 (转)

    出处:  SpringMVC实现全局异常处理器 我们知道,系统中异常包括:编译时异常和运行时异常RuntimeException,前者通过捕获异常从而获取异常信息,后者主要通过规范代码开发.测试通过手 ...

  8. CentOS7 安装ffmpeg

    安装EPEL Release,因为安装需要使用其他的repo源,所以需要EPEL支持:yum install -y epel-release#如果出现缺少Code提示,可以: sudo rpm --i ...

  9. Momentum Contrast for Unsupervised Visual Representation Learning

    Momentum Contrast for Unsupervised Visual Representation Learning 一.Methods Previously Proposed 1. E ...

  10. O021、创建 Image

    参考https://www.cnblogs.com/CloudMan6/p/5393376.html   本节演示如何通过 Web GUI 和 CLI 两种方法创建image.   OpenStack ...