Vijos 1565 多边形 【区间DP】

描述

zgx给了你一个n边的多边形,这个多边形每个顶点赋予一个值,每条边都被标上运算符号+或*,对于这个多边形有一个游戏,游戏的步骤如下:
(1)第一步,删掉一条边;
(2)接下来n-1步,每步对剩下的边中的一条进行操作,用一个新的顶点取代这条边。将这条被取代的边两端的顶点的整数值通过边上的运算得到的结果赋予新顶点。

最后,所有的边被删除,只剩一个定点,这个定点的整数值就是游戏的最后得分。

你要做的就是算出给你的多边形能得到的最高分和最低分。

格式

输入格式

第一行,n;
第二行,n条边的运算符;
第三行,n个顶点的初始值;

注:边和顶点都是按顺序输入,
第一个输入的边连接第一个输入的第二个输入的顶点。

输出格式

最大值;
最小值。

样例1

样例输入1

4
+++*
1 1 1 1

样例输出1

4
3

限制

各个测试点2s

提示

n<=50
解释样例:
1
+ +
1 1
* +
1
最大值:1+1+1+1=4或(1+1)*(1+1);
最小值:1*1+1+1=3;

题目链接:

  https://www.vijos.org/p/1565

题目大意:

  N个数顺序排成一个圈,每两个数之间有一条边,+或*

  题目要求删去一条边之后,任意顺序删掉一条边,并且把这条边两边的端点按照边上的符号运算,求最大最小值。

题目思路:

  【区间DP】

  可能是负数!!!

  一开始居然傻逼的去做符号。。

  首先破环,复制一遍数组到i+n。接着区间DP

  max[i][j]和min[i][j]表示第i个数到第j个数所能获得的最大值和最小值。

  然后枚举中间的断点。注意乘号的时候max=max*max,min*min。min=min*min,max*min。

  1 //
  2 //by coolxxx
  3 /*
  4 #include<iostream>
  5 #include<algorithm>
  6 #include<string>
  7 #include<iomanip>
  8 #include<map>
  9 #include<stack>
 10 #include<queue>
 11 #include<set>
 12 #include<bitset>
 13 #include<memory.h>
 14 #include<time.h>
 15 #include<stdio.h>
 16 #include<stdlib.h>
 17 #include<string.h>
 18 #include<math.h>
 19 //#include<stdbool.h>
 20 #define min(a,b) ((a)<(b)?(a):(b))
 21 #define max(a,b) ((a)>(b)?(a):(b))
 22 #define swap(a,b) ((a)^=(b),(b)^=(a),(a)^=(b))
 23 */
 24 #include<bits/stdc++.h>
 25 #pragma comment(linker,"/STACK:1024000000,1024000000")
 26 #define abs(a) ((a)>0?(a):(-(a)))
 27 #define lowbit(a) (a&(-a))
 28 #define sqr(a) ((a)*(a))
 29 #define mem(a,b) memset(a,b,sizeof(a))
 30 #define eps (1e-8)
 31 #define J 10000
 32 #define mod 1000000007
 33 #define MAX 0x7f7f7f7f
 34 #define PI 3.14159265358979323
 35 #define N 104
 36 using namespace std;
 37 typedef long long LL;
 38 double anss;
 39 LL aans;
 40 int cas,cass;
 41 int n,m,lll,ans;
 42
 43 LL a[N];
 44 char ch[N];
 45 bool c[N];
 46 LL maxx[N][N],minn[N][N];
 47 int main()
 48 {
 49     #ifndef ONLINE_JUDGE
 50     freopen("1.txt","r",stdin);
 51 //    freopen("2.txt","w",stdout);
 52     #endif
 53     int i,j,k,l;
 54     int x,y,z;
 55 //    for(scanf("%d",&cass);cass;cass--)
 56 //    for(scanf("%d",&cas),cass=1;cass<=cas;cass++)
 57 //    while(~scanf("%s",s))
 58     while(~scanf("%d",&n))
 59     {
 60         for(i=0;i<N;i++)
 61             for(j=0;j<N;j++)
 62                 maxx[i][j]=-MAX,minn[i][j]=MAX;
 63
 64         scanf("%s",ch+1);
 65         for(i=1;i<=n;i++)
 66         {
 67             if(ch[i]==‘*‘)c[i+n]=c[i]=1;
 68             else c[i+n]=c[i]=0;
 69         }
 70         for(i=1;i<=n;i++)
 71         {
 72             scanf("%lld",&a[i]);
 73             a[n+i]=a[i];
 74             maxx[i][i]=maxx[i+n][i+n]=minn[i][i]=minn[i+n][i+n]=a[i];
 75         }
 76         for(l=1;l<n;l++)
 77         {
 78             for(i=1;i+l<=n+n;i++)
 79             {
 80                 j=i+l;
 81                 for(k=i;k<j;k++)
 82                 {
 83                     if(c[k])
 84                     {
 85                         maxx[i][j]=max(maxx[i][j],maxx[i][k]*maxx[k+1][j]);
 86                         maxx[i][j]=max(maxx[i][j],minn[i][k]*minn[k+1][j]);
 87
 88                         minn[i][j]=min(minn[i][j],minn[i][k]*minn[k+1][j]);
 89                         minn[i][j]=min(minn[i][j],maxx[i][k]*minn[k+1][j]);
 90                         minn[i][j]=min(minn[i][j],minn[i][k]*maxx[k+1][j]);
 91                     }
 92                     else
 93                     {
 94                         maxx[i][j]=max(maxx[i][j],maxx[i][k]+maxx[k+1][j]);
 95                         minn[i][j]=min(minn[i][j],minn[i][k]+minn[k+1][j]);
 96                     }
 97                 }
 98             }
 99         }
100         LL Min=MAX,Max=-MAX;
101         for(i=1;i<=n;i++)
102         {
103             Min=min(Min,minn[i][i+n-1]);
104             Max=max(Max,maxx[i][i+n-1]);
105         }
106         printf("%lld\n%lld\n",Max,Min);
107         puts("");
108     }
109     return 0;
110 }
111 /*
112 //
113
114 //
115 */

时间: 2024-10-13 00:11:21

Vijos 1565 多边形 【区间DP】的相关文章

Hzoi 2018.2.11多边形 区间DP

给定一个由N个顶点构成的多边形,每个顶点被赋予一个整数值,而每条边则被赋予一个符号:+(加法运算)或者*(乘法运算),所有边依次用整数1到N标识. 一个多边形的图形表示 首次移动,允许将某条边删除: 接下来的每次顺序移动包括下面步骤: 1.选出一条边E,以及由E联接的顶点V1和V2: 2.用一个新的顶点,取代边E及其所联接的两个顶点V1和V2.新顶点要赋予新的值,这个值是对V1和V2,做由E所指定的运算,所得到的结果. 所有边都被删除后,只剩下一个顶点,游戏结束.游戏的得分就是该顶点的数值. 任

Vijos 1451 圆环取数 【区间DP】

背景 小K攒足了路费来到了教主所在的宫殿门前,但是当小K要进去的时候,却发现了要与教主守护者进行一个特殊的游戏,只有取到了最大值才能进去Orz教主-- 描述 守护者拿出被划分为n个格子的一个圆环,每个格子上都有一个正整数,并且定义两个格子的距离为两个格子之间的格子数的最小值.环的圆心处固定了一个指针,一开始指向了圆环上的某一个格子,你可以取下指针所指的那个格子里的数以及与这个格子距离不大于k的格子的数,取一个数的代价即这个数的值.指针是可以转动的,每次转动可以将指针由一个格子转向其相邻的格子,且

Vijos 1100 (区间DP)

题目链接: https://vijos.org/p/1100 题目大意:NOIP著名的加分二叉树.给出一棵树的中序遍历,加分规则左子树*右子树+根.空子树分数为1.问最大加分的树结构,输出树结构的先序遍历. 解题思路: 先从小的问题看起. 对于一棵子树,只要知道根是啥,就能轻松求出这棵子树的加分情况. 那么就变成枚举根的区间DP问题. 由于要输出先序遍历,则用m[i][j]记录在i~j区间选择的根. 区间DP边界: ①一个点情况:即无左右子树,dp[i][i]=node[i],m[i][i]=i

ZOJ 3537 Cake 求凸包 区间DP

题意:给出一些点表示多边形顶点的位置(如果多边形是凹多边形就不能切),切多边形时每次只能在顶点和顶点间切,每切一次都有相应的代价.现在已经给出计算代价的公式,问把多边形切成最多个不相交三角形的最小代价是多少. 思路:首先判断多边形是否是凸多边形,之后就是区间dp了. 求出凸包后,按逆时针来看. 设置dp[i][j]为从顶点i到顶点j所围成凸多边形的最优解. 枚举切点k (i < k < j) dp[i][j] = min(dp[i][k] + dp[k][j] + cost[i][k] + c

Codeforces 437E The Child and Polygon(区间DP)

题目链接:Codeforces 437E The Child and Polygon 题目大意:给出一个多边形,问说有多少种分割方法,将多边形分割为多个三角形. 解题思路:首先要理解向量叉积的性质,一开始将给出的点转换成顺时针,然后用区间dp计算.dp[i][j]表示从点i到点j可以有dp[i][j]种切割方法.然后点i和点j是否可以做为切割线,要经过判断,即在i和j中选择的话点k的话,点k要在i,j的逆时针方. #include <cstdio> #include <cstring&g

UVA 1331 Minimax Triangulation 区间DP

区间DP: 将一个多边形三角剖分,让可以得到的最大三角形的面积最小 dp[i][j]表示从i点到j点的最优值,枚举中间点k dp[i][j]=min(dp[i][j],max(area(i,j,k),max(dp[i][k],dp[k][j]))); 注意如果中间三角形i-j-k中有其他的点,这样的三角形是不可以剖分的 Minimax Triangulation Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld

POJ 1179 Polygon 区间DP

链接:http://poj.org/problem?id=1179 题意:给出一个多边形,多边形的每个顶点是一个数字,每条边是一个运算符号"+"或者"x".要求的过程如下,手下移除一条边,即这条边不做运算.之后每次移除一条边,将其两边的数字进行对应边的运算,用得到的数字来替代原来的两个点.要求所有边都移除以后得到的最大的答案. 思路:典型的区间DP,在过程中每次操作的处理方式为dp_max[i][j]=dp[i][k]*dp[k+1][j],dp_max[i][j]

Uva 1331 - Minimax Triangulation(最优三角剖分 区间DP)

题目大意:按照顺时针或者逆时针的顺序给出多边的点,要将这个多边形分解成n-2个三角形,要求使得这些三角行中面积最大的三角形面积尽量小,求最小值. 思路:用区间DP可以很方便解决,多边形可能是凹边形,注意剖分的三角形必须在多边形内部,所以可以去掉剖分的三角形中包含其他点,但是其他的在多边形外部的三角形没想到其他方法去除,却ac了,不懂为何 // Accepted C++ 0.042 #include<cstdio> #include<iostream> #include<alg

ZOJ 3537 Cake(凸包+区间DP)

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3537 题目大意:给出一些点表示多边形顶点的位置,如果不是凸多边形(凸包)则不能切,直接输出"I can't cut."切多边形时每次只能在顶点和顶点间切,每切一次的花费为 cost(i, j) = |xi + xj| * |yi + yj| % p.问把多边形切成最多个不相交三角形的最小代价是多少. 解题思路:先求出凸包,接着可以用区间DP解决,设dp