多边形游戏(经典的环形dp)

描述

一个多边形,开始有n个顶点。每个顶点被赋予一个正整数值,每条边被赋予一个运算符“+”或“*”。所有边依次用整数从1到n编号。

现在来玩一个游戏,该游戏共有n步:

第1步,选择一条边,将其删除

随后n-1步,每一步都按以下方式操作:(1)选择一条边E以及由E连接着的2个顶点v1和v2; (2)用一个新的顶点取代边E以及由E连接着的2个顶点v1和v2,将顶点v1和v2的整数值通过边E上的运算得到的结果值赋给新顶点。

最后,所有边都被删除,只剩一个顶点,游戏结束。游戏得分就是所剩顶点上的整数值。那么这个整数值最大为多少?

输入

第一行为多边形的顶点数n(n ≤ 50),其后有n行,每行为一个整数和一个字符,整数为顶点上的正整数值,字符为该顶点到下一个顶点间连边上的运算符“+”或“*”(最后一个字符为最后一个顶点到第一个顶点间连边上的运算符)。

输出

输出仅一个整数,即游戏所计算出的最大值。

题解:

非常经典的环形dp

首先我们可以发现删掉的边数一定是n-1,这样的话操作序列其实是一条包含n个顶点的链。

这个图可以分成一些长度为1,2,3…n的链,这里的长度指的是链所包含的定点数。

我们设f[i][j][0]为以顶点i为起点,长度为j的链的最大值。

f[i][j][1]为以顶点i为起点,长度为j的链的最小值。

那么我们最后的答案就是f[i][n][0] (1<=i<=n);

现在考虑转移。

转移也是用的非常经典的方法。

枚举从当前链的那条边断开,由于断开的两条子链我们已经算出来了,所以就满足了最优子结构。

值得注意的地方是如果断开的那条边上的运算符是乘号,由于数据中可能有负数,所以会出现负负得正的情况

设子链a的最小值为x最大值为y,子链b的最小值为xx,最大值为yy

则该链的最大值为max(x*xx , x*yy, y*xx , y*yy);

最小值为min( x*xx , x*yy, y*xx , y*yy);

因为是环形,所以算顶点的时候需要模n;

#include<iostream>
using namespace std;
int n,v[1001],f[101][101][2],temp,a,b,c,d,ans,tt;
char op[1001],ch;
int main()
{
    cin>>n;
    for (int i=1;i<=n;i++)
      cin>>v[i]>>op[i];
    for (int i=1;i<=n;i++)
      f[i][1][0]=f[i][1][1]=v[i];
    for (int j=2;j<=n;j++)
      for (int i=1;i<=n;i++)
        for (int k=0;k<=j-2;k++)
          {
             temp=(i+k)%n;
             if (temp==0) temp=n;
             tt=(i+k+1)%n;
             if (tt==0) tt=n;
             ch=op[temp];
             if (ch==‘+‘)
              {
                 f[i][j][1]=max(f[i][k+1][1]+f[tt][j-k-1][1],f[i][j][1]);
                 f[i][j][0]=min(f[i][k+1][0]+f[tt][j-k-1][0],f[i][j][0]);
              }
             if (ch==‘*‘)
              {
                a=f[i][k+1][1]*f[tt][j-k-1][1];
                b=f[i][k+1][1]*f[tt][j-k-1][0];
                c=f[i][k+1][0]*f[tt][j-k-1][1];
                d=f[i][k+1][0]*f[tt][j-k-1][0];
                f[i][j][1]=max(max(max(a,b),max(c,d)),f[i][j][1]);
                f[i][j][0]=min((min(a,b),min(c,d)),f[i][j][0]);
              }
          }
    ans=-100000000;
   for (int i=1;i<=n;i++)
     ans=max(ans,f[i][n][1]);
    cout<<ans;
}
时间: 2024-08-10 08:47:04

多边形游戏(经典的环形dp)的相关文章

codevs1085数字游戏(环形DP+划分DP )

1085 数字游戏 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 丁丁最近沉迷于一个数字游戏之中.这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则下想要赢得这个游戏并不那么容易.游戏是这样的,在你面前有一圈整数(一共n个),你要按顺序将其分为m个部分,各部分内的数字相加,相加所得的m个结果对10取模后再相乘,最终得到一个数k.游戏的要求是使你所得的k最大或者最小. 例如,对于下面这圈数字(n=4,m=2): 2

NOIP2009pj道路游戏[环形DP 转移优化 二维信息]

题目描述 小新正在玩一个简单的电脑游戏. 游戏中有一条环形马路,马路上有 n 个机器人工厂,两个相邻机器人工厂之间由一小段马路连接.小新以某个机器人工厂为起点,按顺时针顺序依次将这 n 个机器人工厂编号为1~n,因为马路是环形的,所以第 n 个机器人工厂和第 1 个机器人工厂是由一段马路连接在一起的.小新将连接机器人工厂的这 n 段马路也编号为 1~n,并规定第 i 段马路连接第 i 个机器人工厂和第 i+1 个机器人工厂(1≤i≤n-1),第 n 段马路连接第 n 个机器人工厂和第 1个机器人

多边形游戏(DP)

Description 多边形游戏是一个单人玩的游戏,开始时有一个由n个顶点构成的多边形.每个顶点被赋予一个整数值,每条边被赋予一个运算符 "+" 或 "*".所有边依次用整数从1到n编号. 游戏第1步,将一条边删除. 随后的n-1步按以下方式操作: (1)选择一条边E以及由E连接着的两个顶点V1和V2: (2)用一个新的顶点取代边E以及由E连接着的两个顶点V1和V2.将由顶点V1和V2的整数值通过边E上的运算得到的结果赋予新顶点. 最后,所有边都被删除,游戏结束.

区间dp与环形dp

区间dp 常见题型 求区间[1,n]XXXXX后的最大/小值,一般分为无要求或只能/最多分成m段两类 做法 如对分段无要求,设dp[i][j]表示序列中[i,j]的最值,最外层循环区间长度,第二层循环左端点,并能确定右端点,第三层枚举断点: for(rint len = 1;len <= n; ++len) {//如果对len == 1初始化了可从2枚举 for(rint i = 1,j = i + len - 1;j <= n;++i,++j) { for(rint k = i;k <

动规-多边形游戏

1.题目描述 多边形游戏大概是这样的:看下面的一幅图: 有一个多边形,节点处是数字,边上是运算符,这里只考虑"+"和"*"两种,两个点的数与他们之间的运算符进行运算后的结果数构成新的节点,这样运算到最后只剩一个数,我们要求得能够运算出的最大的数. 2.代码 #include <stdio.h> #include <iostream> using namespace std; int ***m; char *op; void MinMax(in

ZOJ2599:Graduated Lexicographical Ordering(非常经典的数位DP)

Consider integer numbers from 1 to n. Let us call the sum of digits of an integer number its weight. Denote the weight of the number x as w(x). Now let us order the numbers using so called graduated lexicographical ordering, or shorter grlex ordering

石子合并【环形DP】

先放上luogu的石子合并题目链接 这是一道环形DP题,思想和能量项链很像,在预处理过程中的手法跟乘积最大相像. 用一个m[][]数组来存储石子数量,m[i][j]表示从第 i 堆石子到第 j 堆石子的总数. 接下来三重循环 i 表示合并操作的起始位置, j 表示合并操作的终点,也就是把 i 到 j 合并 k表示间断点,即 i 到 j 合并过程中选择k点来作为合并位置 状态转移方程 f[i][j]=max(f[i][j],f[i][k]+f[k+1][j]+m[i][k]+m[k+1][j]);

hdu4035之经典慨率DP

Maze Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others) Total Submission(s): 1419    Accepted Submission(s): 511 Special Judge Problem Description When wake up, lxhgww find himself in a huge maze. The maze consisted b

动态规划--多边形游戏

1.问题描述:   给定N个顶点的多边形,每个顶点标有一个整数,每条边上标有+(加)或是×(乘)号,并且N条边按照顺时针 依次编号为1~N.下图给出了一个N=4个顶点的多边形. 游戏规则 :(1) 首先,移走一条边. (2) 然后进行下面的操作: 选中一条边E,该边有两个相邻的顶点,不妨称为V1和V2.对V1和V2顶点所标的整数按照E上所标运算符号(+或是×)进行运算,得到一个整数:用该整数标注一个新顶点,该顶点代替V1和V2 . 持续进行此操作,直到最后没有边存在,即只剩下一个顶点.该顶点的整