• 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
    %lld
    ",Max,Min);
    107         puts("");
    108     }
    109     return 0;
    110 }
    111 /*
    112 //
    113 
    114 //
    115 */
    View Code
  • 相关阅读:
    Codeforces Round #649 (Div. 2) D. Ehab's Last Corollary
    Educational Codeforces Round 89 (Rated for Div. 2) E. Two Arrays
    Educational Codeforces Round 89 (Rated for Div. 2) D. Two Divisors
    Codeforces Round #647 (Div. 2) E. Johnny and Grandmaster
    Codeforces Round #647 (Div. 2) F. Johnny and Megan's Necklace
    Codeforces Round #648 (Div. 2) G. Secure Password
    Codeforces Round #646 (Div. 2) F. Rotating Substrings
    C++STL常见用法
    各类学习慕课(不定期更新
    高阶等差数列
  • 原文地址:https://www.cnblogs.com/Coolxxx/p/6555406.html
Copyright © 2020-2023  润新知