Vijos 1565 多边形 区间DP

Posted Coolxxx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 */
View Code

 

以上是关于Vijos 1565 多边形 区间DP的主要内容,如果未能解决你的问题,请参考以下文章

Vijos 1451 圆环取数 区间DP

加分二叉树 vijos1991 NOIP2003第三题 区间DP/树形DP/记忆化搜索

ZOJ 3537 Cake 求凸包 区间DP

[DP 区间 剖分 高精] 凸多边形划分

区间dp+四边形不等式优化

多边形游戏 /// 区间DP oj1903