多边形游戏——区间dp
题目描述
多边形(Polygon)游戏是单人玩的游戏,开始的时候给定一个由N个顶点构成的多边形(图1所示的例子中,N=4),每个顶点被赋予一个整数值,而每条边则被赋予一个符号:+(加法运算)或者*(乘法运算),所有边依次用整数1到N标识。
图1:一个多边形的图形表示 首次移动(first move),允许将某条边删除; 接下来的每次顺序移动(subsequentmoves),包括下面步骤:
1、选出一条边E,以及由E联接的顶点V1和V2;
2、用一个新的顶点,取代边E及其所联接的两个顶点V1和V2。新顶点要赋予新的值,这个值是对V1和V2,做由E所指定的运算,所得到的结果。
所有边都被删除后,只剩下一个顶点,游戏结束。游戏的得分就是该顶点的数值。 下面是一个游戏实例: 考虑图1中的多边形。
玩家第一步删除第3条边。结果如图2所示。
图2 删除第3条边
之后,玩家删除第1条边
图3 删除第1条边
然后删除第4条边,
图4 删除第4条边
最后删除第2条边。得分是0.
图5 删除第2条边 任务: 编写一个程序,对于任意给定的多边形,计算可能的最高得分,并且列举出所有的可以导致最高得分的被首次移动的边。
输入格式
文件POLYGON.IN给出的是,由N个顶点构成的多边形。文件包括2行: 第一行记录的是数值N(n<=50); 第二行包含所有边(1,…,N)分别被赋予的符号,以及嵌入到两条边之间的顶点的数值(第一个整数值对应于与1号、2号边同时相连的顶点;第二个整数对应于与2号、3号边同时相连的顶点;…;等等。最后一个数值对应于与N号、1号边同时相连的顶点),符号和数值之间由一个空格分隔。边的符号有2种:字母t(对应于+),字母x(对应于*)。
输出格式
在文件POLYGON.OUT的第一行,你的程序必须输出在输入文件指定条件下可能得到的最高得分。 有些边如果在首次移动中被删除,可以导致最高得分。在输出文件的第二行,要求列举出所有这样的边,而且按照升序输出,其间用一个空格分开。
样例
样例输入
4
t -7 t 4 x 2 x 5
样例输出
33
1 2
数据范围与提示
样例输入对应于图1所示的多边形。第二行的第一个字符是1号边的符号。
此题类似石子合并,将环状多边形转换成链,由n转入2*n+1个字符。
总数量不能变,所以一点一点向后推移;
先进行一个循环,决定去掉那条边,再加n,向后推移;
f[i][j],表示从i到j的最优解;
每一个点必定是由两个点组成,so,在i,j区间枚举分割点,注意分割点不能等于j;
因为这题中,数字有正有负,必然要考虑负负得正的情况
例如,-1000*-1000=1000000 100*100=10000 而1000000>10000,但-1000却小于100;
所以每一次合并必然要考虑最小值和最大值;
如果下一次合并时,符号是‘+’,那就直接将最大值和最小值相加;
若是‘*’,那就将大*大,大*小,小*大,小*小四种比较一下,寻找最大值和最小值;
代码
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int n,shu[150],f[150][150][3],sum[150][150],ff[150]={0},ma,mb,a,b,c,d;
char fu[150];
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>fu[i]>>shu[i];//先输入符号,在输入数字
}
for(int i=n+1;i<=2*n;i++)
{
shu[i]=shu[i-n];
fu[i]=fu[i-n];
}
for(int i=1;i<=n;i++)
{
for(int o=1;o<=2*n;o++)
{
for(int p=1;p<=2*n;p++)
{
f[o][p][1]=-9999999;//求大值,初始化最小
f[o][p][2]=9999999;//求小值,初始化最大
}
}
for(int q=1;q<=2*n;q++)//初始化区间dp
{
f[q][q][1]=shu[q];
f[q][q][2]=shu[q];
if(fu[q+1]=='t')
{
f[q][q+1][1]=shu[q]+shu[q+1];
f[q][q+1][2]=shu[q]+shu[q+1];
}
if(fu[q+1]=='x')
{
f[q][q+1][1]=shu[q]*shu[q+1];
f[q][q+1][2]=shu[q]*shu[q+1];
}
}
for(int l=2;l<=n;l++)
{
for(int j=i;j<=i+n-l;j++)
{
int k=j+l-1;
for(int x=j;x<k;x++)//一定要小于k,因为后面有x+1;
{
if(fu[x+1]=='t'&&f[j][k][1]<f[j][x][1]+f[x+1][k][1])f[j][k][1]=f[j][x][1]+f[x+1][k][1];
if(fu[x+1]=='t'&&f[j][k][2]>f[j][x][2]+f[x+1][k][2])f[j][k][2]=f[j][x][2]+f[x+1][k][2];
if(fu[x+1]=='x')
{
a=f[j][x][1]*f[x+1][k][1];
b=f[j][x][2]*f[x+1][k][1];
c=f[j][x][1]*f[x+1][k][2];
d=f[j][x][2]*f[x+1][k][2];
f[j][k][1]=max(max(max(a,b),max(c,d)),f[j][k][1]);
f[j][k][2]=min(min(min(a,b),min(c,d)),f[j][k][2]);
}
}
}
}
ff[i]=f[i][i+n-1][1];
}
ma=-1000000;
for(int i=1;i<=n;i++)//寻找最大值
{
if(ma<ff[i])
{
ma=ff[i];
mb=i;
}
}
cout<<ma<<endl;
for(int i=1;i<=n;i++)
{
if(ff[i]==ma)
{
cout<<i<<" ";//输出可以断第几个
}
}
}
/*
4 120
x 2 x 3 x 4 x 5 1 2 3 4 6 10000
x -10 x -10 x -10 t 10 t 10 t 10 6 7 300000
x -10 x -10 x -10 x -10 t 10 t 10 t 10 5
以上是三组测试数据*/
以上是个人见解,,如有不妥请评论区发表意见
以下是改进后的代码
#include<bits/stdc++.h>
using namespace std;
int n,num[105],dp1[105][105],dp2[105][105],maxn[55],maxx;
char fu[105];
int main()
{
memset(dp1,0x8f,sizeof(dp1));
memset(dp2,0x3f,sizeof(dp2));
cin>>n;
for(int i=1;i<=n;i++){
cin>>fu[i]>>num[i];
fu[n+i]=fu[i];
num[n+i]=dp1[i][i]=dp1[n+i][n+i]=dp2[i][i]=dp2[n+i][n+i]=num[i];
}
for(int o=1;o<=n;o++){
for(int l=2;l<=n;l++){
for(int i=o;i<=o+n-l;i++){
int j=i+l-1;
for(int k=i+1;k<=j;k++){
int a,b,c,d;
if(fu[k]=='t'){
a=dp1[i][k-1]+dp1[k][j];
b=dp2[i][k-1]+dp2[k][j];
dp1[i][j]=max(dp1[i][j],a);
dp2[i][j]=min(dp2[i][j],b);
}
if(fu[k]=='x'){
a=dp1[i][k-1]*dp1[k][j];
b=dp1[i][k-1]*dp2[k][j];
c=dp2[i][k-1]*dp2[k][j];
d=dp2[i][k-1]*dp1[k][j];
dp1[i][j]=max(dp1[i][j],max(a,max(b,max(c,d))));
dp2[i][j]=min(dp2[i][j],min(a,min(b,min(c,d))));
}
}
}
}
maxn[o]=dp1[o][o+n-1];
maxx=max(maxx,dp1[o][o+n-1]);
}
cout<<maxx<<endl;
for(int i=1;i<=n;i++){
if(maxn[i]==maxx)
cout<<i<<" ";
}
}
多边形游戏——区间dp的更多相关文章
- 多边形游戏 /// 区间DP oj1903
题目大意: ... Input 输入的第一行是单独一个整数n( 3 ≤ n ≤ 18 ),表示多边形的顶点数(同时也是边数). 接下来第n行,每行包含一个运算符("+"或" ...
- Vijos 1565 多边形 【区间DP】
描述 zgx给了你一个n边的多边形,这个多边形每个顶点赋予一个值,每条边都被标上运算符号+或*,对于这个多边形有一个游戏,游戏的步骤如下:(1)第一步,删掉一条边:(2)接下来n-1步,每步对剩下的边 ...
- P1005 矩阵取数游戏[区间dp]
题目描述 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的\(m*n\)的矩阵,矩阵中的每个元素\(a_{i,j}\)均为非负整数.游戏规则如下: 每次取数时须从每行各取走一个元素,共n个.经过m次后 ...
- 圆桌游戏(区间DP)
2.圆桌游戏 (game.cpp/c/pas) [问题描述] 有一种圆桌游戏是这样进行的:n个人围着圆桌坐成一圈,按顺时针顺序依次标号为1号至n号.对1<=i<=n的i来说,i号的左边是i ...
- BZOJ 2121: 字符串游戏 区间DP + 思维
Description BX正在进行一个字符串游戏,他手上有一个字符串L,以及其他一些字符串的集合S,然后他可以进行以下操作:对 于一个在集合S中的字符串p,如果p在L中出现,BX就可以选择是否将其删 ...
- 洛谷 P1043 数字游戏 区间DP
题目描述 丁丁最近沉迷于一个数字游戏之中.这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则下想要赢得这个游戏并不那么容易.游戏是这样的,在你面前有一圈整数(一共n个),你要按顺序将其分 ...
- qscoj 喵哈哈村的打印机游戏 区间dp
点这里去看题 区间dp ,dp[l][r][d]代表从l到r的区间底色为d,具体看代码 第一次见到区间dp...两个小时对着敲了五遍终于自己敲懂了一遍ac #include<bits/stdc+ ...
- 多边形游戏(DP)
Description 多边形游戏是一个单人玩的游戏,开始时有一个由n个顶点构成的多边形.每个顶点被赋予一个整数值,每条边被赋予一个运算符 "+" 或 "*". ...
- 【bzoj2121】字符串游戏 区间dp
题目描述 给你一个字符串L和一个字符串集合S,如果S的某个子串在S集合中,那么可以将其删去,剩余的部分拼到一起成为新的L串.问:最后剩下的串长度的最小值. 输入 输入的第一行包含一个字符串,表示L. ...
随机推荐
- 关于Spring Boot 多数据源的事务管理
自己的一些理解:自从用了Spring Boot 以来,这近乎零配置和"约定大于配置"的设计范式用着确实爽,其实对零配置的理解是:应该说可以是零配置可以跑一个简单的项目,因为Spri ...
- Linux中数据库的安装和配置(MySQL与Maria DB)
目录 MySQL和Maria DB的介绍 MySQL和Maria DB的安装 yum源安装MySQL(Centos6.5+Mysql5.1) 源码包安装MySQL yum源安装Maria DB 源码包 ...
- Tomcat容器、JSP和Servlet
目录 JSP Tomcat.JSP和Servlet JSP JSP全名为Java Server Pages,其根本是一个简化的Servlet设计.JSP技术有点类似ASP技术,它是在传统的HTML网页 ...
- POJ1376简单广搜
题意: 给你一个n*m的矩阵,然后给你机器人的起点和终点,还有起点的方向,然后每次机器人有两种操作,左右旋转90度,或者是朝着原来的方向走1,2或者3步,机器人再走的过程中不能碰到格子,也 ...
- Linux-鸟菜-6-文件搜索
Linux-鸟菜-6-文件搜索 which(寻找[执行档]) alian ..............这个后面显示的是别名 没有找到history是因为which是根据PATH环境变阿玲去搜索执行文件 ...
- ERROR: Symbol file could not be found 寒江孤钓<<windows 内核安全编程>> 学习笔记
手动下载了Symbols,设置好了Symbols File Path,串口连接上了以后,出现ERROR: Symbol file could not be found, 并且会一直不停的出现windb ...
- XCTF-supersqli
supersqli 进来有个输入框,看内容应该是var_dump了sql查询结果 单引号有报错,万能语句能用,注释符#没被ban 打了个union select,给提示ban了一堆关键字,而且忽略大小 ...
- 日志框架整合报错Class path contains multiple SLF4J bindings.
在进行SSM框架的日志框架统一管理时,报错Class path contains multiple SLF4J bindings 如下图 意思是类路径下包含重复的SLF4J绑定,然后给出了重复的两个全 ...
- burp-suite(Web安全测试工具)教程
Burp Suite 是用于攻击web 应用程序的集成平台.它包含了许多工具,并为这些工具设计了许多接口,以促进加快攻击应用程序的过程.所有的工具都共享一个能处理并显示HTTP 消息,持久性,认证,代 ...
- 『动善时』JMeter基础 — 12、JMeter取样器详解:sampler
目录 1.取样器介绍 2.JMeter自带的取样器 3."HTTP请求"为例介绍一下取样器 (1)HTTP Request: (2)Web服务器: (3)HTTP请求: (4)同请 ...