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

题目大意:

...

Input

输入的第一行是单独一个整数n( 3 ≤ n ≤ 18 ),表示多边形的顶点数(同时也是边数)。

接下来第n行,每行包含一个运算符("+"或"*")和一个整数V[i]( -10 < V[i] < 10 ),分别表示第i条边所对应的运算符和第i个顶点上的数值。

Output

输出只有一个整数,表示最高得分W ( -231 < W < 231 )。

Sample Input

3
+ 2
* 3
+ 1

Sample Output

9

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
#define ll long long
using namespace std;
char e[105];
ll d[105],dp0[105][105],dp1[105][105];
/// 存在负数的情况 乘法时负负得正 所有要同时维护最大值和最小值
int main()
{
    int n; scanf("%d\n",&n);
    for(int i=0;i<n;i++)
    {
        cin>>e[(i+n-1)%n]>>d[i];
        dp0[i][1]=dp1[i][1]=d[i];
    }
    /// 默认删除 选择的起点的前一条边
    for(int r=2;r<=n;r++)
        for(int i=0;i<n;i++)
        {
            dp0[i][r]=INF, dp1[i][r]=-INF;
            for(int k=1;k<r;k++)
            {
                ll  a=dp0[i][k], b=dp0[(i+k)%n][r-k],
                    c=dp1[i][k], d=dp1[(i+k)%n][r-k];
                /// 注意由于是环形 这两处必须取模
                if(e[(i+k-1)%n]==‘*‘)
                {
                    ll tmp[4]={a*b,a*d,c*b,c*d};
                    sort(tmp,tmp+4);
                    dp0[i][r]=min(dp0[i][r],tmp[0]),
                    dp1[i][r]=max(dp1[i][r],tmp[3]);
                }
                else
                {
                    dp0[i][r]=min(dp0[i][r],a+b);
                    dp1[i][r]=max(dp1[i][r],c+d);
                }
            }
        }
    ll ans=0;
    for(int i=0;i<n;i++)
        ans=max(ans,dp1[i][n]);
    printf("%lld\n",ans);

    return 0;
}

原文地址:https://www.cnblogs.com/zquzjx/p/9096099.html

时间: 2024-08-01 18:06:46

多边形游戏 /// 区间DP oj1903的相关文章

Vijos 1565 多边形 【区间DP】

描述 zgx给了你一个n边的多边形,这个多边形每个顶点赋予一个值,每条边都被标上运算符号+或*,对于这个多边形有一个游戏,游戏的步骤如下:(1)第一步,删掉一条边:(2)接下来n-1步,每步对剩下的边中的一条进行操作,用一个新的顶点取代这条边.将这条被取代的边两端的顶点的整数值通过边上的运算得到的结果赋予新顶点. 最后,所有的边被删除,只剩一个定点,这个定点的整数值就是游戏的最后得分. 你要做的就是算出给你的多边形能得到的最高分和最低分. 格式 输入格式 第一行,n;第二行,n条边的运算符:第三

qscoj 喵哈哈村的打印机游戏 区间dp

点这里去看题 区间dp ,dp[l][r][d]代表从l到r的区间底色为d,具体看代码 第一次见到区间dp...两个小时对着敲了五遍终于自己敲懂了一遍ac #include<bits/stdc++.h> using namespace std; int dp[55][55][55]; string s; int solve(int l,int r,int d) { if(l>r)return 0; if(l==r&&s[l]-'A'==d)return dp[l][r][

多边形游戏(DP)

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

【bzoj2121】字符串游戏 区间dp

题目描述 给你一个字符串L和一个字符串集合S,如果S的某个子串在S集合中,那么可以将其删去,剩余的部分拼到一起成为新的L串.问:最后剩下的串长度的最小值. 输入 输入的第一行包含一个字符串,表示L. 第二行包含一个数字n,表示集合S中元素个数. 以下n行,每行一个字符串,表示S中的一个元素. 输入字符串都只包含小写字母. 输出 输出一个整数,表示L的最短长度. 样例输入 aaabccd3acabcaaa 样例输出 2 题解 我们考虑:每次删除连续的一段,对应到原串上即:删除 $[l,r]$ 中所

1166 矩阵取数游戏[区间dp+高精度]

1166 矩阵取数游戏 2007年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题解 题目描述 Description [问题描述]帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m 的矩阵,矩阵中的每个元素aij均为非负整数.游戏规则如下:1. 每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素:2. 每次取走的各个元素只能是该元素所在行的行首或行尾:3. 每次取数都有一个得分值,为每行取数的得分之和,每行取数的得分

算法设计与分析——多边形游戏(DP)

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

luogu P1005 矩阵取数游戏 区间DP

每一行是独立的,分开处理即可. dp[i][j]表示[i,j]这一段,取完的最大收益.转移很显然,dp[i][j] = max(dp[i + 1][j] + 2^(m - (j - l)) * mp[t][i],dp[i][j - 1] + 2^(m - (j - l)) * mp[t][j]) 不想写高精度,python水一发. 1 n,m = map(int,input().split()) 2 res = 0 3 mp = [[0 for i in range(0,80,1)] for i

【日常学习】【区间DP+高精】codevs1166 矩阵取数游戏题解

题目来自NOIP2007TG3 如果在考场上我现在已经歇菜了吧 今天一整天的时间全部投在这道题上,收获不小. 先上题目 题目描述 Description [问题描述] 帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m 的矩阵,矩阵中的每个元素aij均 为非负整数.游戏规则如下: 1. 每次取数时须从每行各取走一个元素,共n个.m次后取完矩阵所有元素: 2. 每次取走的各个元素只能是该元素所在行的行首或行尾: 3. 每次取数都有一个得分值,为每行取数的得分之和,每行取数的得分= 被取走的元素

Luogu P2734 游戏 A Game 区间DP

P2734 游戏 A Game 题目背景 有如下一个双人游戏:N(2 <= N <= 100)个正整数的序列放在一个游戏平台上,游戏由玩家1开始,两人轮流从序列的任意一端取一个数,取数后该数字被去掉并累加到本玩家的得分中,当数取尽时,游戏结束.以最终得分多者为胜. 题目描述 编一个执行最优策略的程序,最优策略就是使玩家在与最好的对手对弈时,能得到的在当前情况下最大的可能的总分的策略.你的程序要始终为第二位玩家执行最优策略. 输入输出格式 输入格式: 第一行: 正整数N, 表示序列中正整数的个数