Acwing-283-多边形(区间DP)
链接:
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)的更多相关文章
- 多边形——————区间dp
原题链接:https://www.acwing.com/problem/content/285/ 题意简单来说就是:给你一个环,断掉一条边使其成为一个链,用这个链跑dp,求最大得分. 首先这不是一道板 ...
- poj1179多边形——区间DP
题目:http://poj.org/problem?id=1179 区间DP,值得注意的是有负值,而且有乘法,因此可能会影响最大值: 注意memset中写-1仅仅是-1,-2才是一个很小的负数: 最后 ...
- Hzoi 2018.2.11多边形 区间DP
给定一个由N个顶点构成的多边形,每个顶点被赋予一个整数值,而每条边则被赋予一个符号:+(加法运算)或者*(乘法运算),所有边依次用整数1到N标识. 一个多边形的图形表示 首次移动,允许将某条边删除: ...
- Vijos 1565 多边形 【区间DP】
描述 zgx给了你一个n边的多边形,这个多边形每个顶点赋予一个值,每条边都被标上运算符号+或*,对于这个多边形有一个游戏,游戏的步骤如下:(1)第一步,删掉一条边:(2)接下来n-1步,每步对剩下的边 ...
- 多边形游戏——区间dp
题目描述 多边形(Polygon)游戏是单人玩的游戏,开始的时候给定一个由N个顶点构成的多边形(图1所示的例子中,N=4),每个顶点被赋予一个整数值,而每条边则被赋予一个符号:+(加法运算)或者*(乘 ...
- kuangbin 区间dp
A - Cake 题目大意:给你一个n个顶点(n<=100)的多边形和每两个点连边的消耗,让你求把这个多边形全部切成三角形所需要的最小消耗,如果这个多边形为凹多边形则输出无解. 思路:先求一个凸 ...
- BZOJ 1719--[Usaco2006 Jan] Roping the Field 麦田巨画(几何&区间dp)
1719: [Usaco2006 Jan] Roping the Field 麦田巨画 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 82 Solved ...
- 区间DP小结
也写了好几天的区间DP了,这里稍微总结一下(感觉还是不怎么会啊!). 但是多多少少也有了点感悟: 一.在有了一点思路之后,一定要先确定好dp数组的含义,不要模糊不清地就去写状态转移方程. 二.还么想好 ...
- ZOJ 3537 Cake(凸包+区间DP)
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3537 题目大意:给出一些点表示多边形顶点的位置,如果不是凸多边形 ...
- ZOJ 3537 Cake 求凸包 区间DP
题意:给出一些点表示多边形顶点的位置(如果多边形是凹多边形就不能切),切多边形时每次只能在顶点和顶点间切,每切一次都有相应的代价.现在已经给出计算代价的公式,问把多边形切成最多个不相交三角形的最小代价 ...
随机推荐
- Zookeeper入门(一)
Zookeeper是分布式服务治理中间件 一.Zookeeper的简介 官方文档上这么解释zookeeper,它是一个分布式服务框架,是Apache Hadoop 的一个子项目,它主要是用 ...
- linux下安转nodejs
转载自:https://www.cnblogs.com/zhuawang/p/7617176.html 在Linux系统安装Nodejs 最简单步骤 1.去官网下载和自己系统匹配的文件: 英文网址:h ...
- PTA(Basic Level)1053.住房空置率
在不打扰居民的前提下,统计住房空置率的一种方法是根据每户用电量的连续变化规律进行判断.判断方法如下: 在观察期内,若存在超过一半的日子用电量低于某给定的阈值 e,则该住房为"可能空置&quo ...
- Largest Number At Least Twice of Others
In a given integer array nums, there is always exactly one largest element. Find whether the largest ...
- 【一道来自老师的题的题解】equip——奇妙的最短路
这道题真的第一眼完全想不到是最短路啊!!!!!!!! 感谢DR大佬讲解!!!!!90°鞠躬 =u= 暂时没有评测网址,(因为需要special judge)敬请期待 机房另一大佬JYY题解,可以对比参 ...
- 2019中山纪念中学夏令营-Day4[JZOJ]
Begin (题目的排序方式:难易程度) 什么是对拍: 对拍是一种在写完程序后,验证自己程序是不是正解的比较方便的方法. 实现过程: 对同一道题,再打一个暴力程序,然后用一些大数据等跑暴力程序来进行验 ...
- 前端html+css标签简介(可能就我自己看的懂-。-)
标签集合 # html 文字标签:修改样式 -<font></font> -属性:size:大小,范围1-7,大于7时默认7 color:颜色,英文单词或者十六进制(editp ...
- Python_3day
循环 循环是一种控制语句块重复执行的结构 while 适用于广度遍历 for 开发中经常使用 while 循环 当一个条件保持真的时候while循环重复执行语句 while 循环一定要有结束条件, ...
- spark教程(七)-文件读取案例
sparkSession 读取 csv 1. 利用 sparkSession 作为 spark 切入点 2. 读取 单个 csv 和 多个 csv from pyspark.sql import Sp ...
- 如何用纯 CSS 创作一个慧星拖尾效果的 loader 动画
效果预览 在线演示 按下右侧的"点击预览"按钮可以在当前页面预览,点击链接可以全屏预览. https://codepen.io/comehope/pen/YLRLaM 可交互视频教 ...