题目链接:http://poj.org/problem?id=1179

Time Limit: 1000MS Memory Limit: 10000K

Description

Polygon is a game for one player that starts on a polygon with N vertices, like the one in Figure 1, where N=4. Each vertex is labelled with an integer and each edge is labelled with either the symbol + (addition) or the symbol * (product). The edges are numbered from 1 to N. 

On the first move, one of the edges is removed. Subsequent moves involve the following steps: 
pick an edge E and the two vertices V1 and V2 that are linked by E; and 
replace them by a new vertex, labelled with the result of performing the operation indicated in E on the labels of V1 and V2. 
The game ends when there are no more edges, and its score is the label of the single vertex remaining.

Consider the polygon of Figure 1. The player started by removing edge 3. After that, the player picked edge 1, then edge 4, and, finally, edge 2. The score is 0. 

Write a program that, given a polygon, computes the highest possible score and lists all the edges that, if removed on the first move, can lead to a game with that score. 

Input

Your program is to read from standard input. The input describes a polygon with N vertices. It contains two lines. On the first line is the number N. The second line contains the labels of edges 1, ..., N, interleaved with the vertices' labels (first that of the vertex between edges 1 and 2, then that of the vertex between edges 2 and 3, and so on, until that of the vertex between edges N and 1), all separated by one space. An edge label is either the letter t (representing +) or the letter x (representing *).

3 <= N <= 50 
For any sequence of moves, vertex labels are in the range [-32768,32767]. 

Output

Your program is to write to standard output. On the first line your program must write the highest score one can get for the input polygon. On the second line it must write the list of all edges that, if removed on the first move, can lead to a game with that score. Edges must be written in increasing order, separated by one space.

Sample Input

4
t -7 t 4 x 2 x 5

Sample Output

33
1 2

题意:

给出一个由无向边和节点组成的环,每个节点上有一个数字,每条边上有一个运算符(加或乘),

现在先割断一条边,然后环就成为一个链,然后你每次可以将这条链上的一条边缩成一个点,产生的新点的权值就是两个节点配合边运算所产生的结果。

不停地缩边成点,直到最后只有一个点为止,求这个点的权值最大是多少。

并给出所有能产生这个最大值的首先割断的边的编号,要求从小到大输出。

题解:

区间DP,周赛上wyb出的毒瘤题,每次两个小区间合并的时候,要记得有可能两个最小的负数相乘可能会产生正数最大值。

因此需要同时维护区间最小值和最大值。

AC代码:

#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
typedef pair<int,int> pii;
const int INF=0x3f3f3f3f;
const int maxn=; int n;
int op[*maxn],nm[*maxn];
pii dp[*maxn][*maxn];
inline int calc(int type,int a,int b){return type?a*b:a+b;}
inline void updatemn(int &x,int y){if(x>y) x=y;}
int solve(int l,int r)
{
for(int s=;s<=r-l+;s++)
{
for(int st=l,ed=st+s-;ed<=r;st++,ed++)
{
dp[st][ed].first=-INF;
dp[st][ed].second=INF;
for(int mid=st+;mid<=ed;mid++)
{
pii le=dp[st][mid-];
pii ri=dp[mid][ed]; int tmp1=calc(op[mid],le.first,ri.first);
dp[st][ed].first=max(dp[st][ed].first,tmp1);
dp[st][ed].second=min(dp[st][ed].second,tmp1); int tmp2=calc(op[mid],le.first,ri.second);
dp[st][ed].first=max(dp[st][ed].first,tmp2);
dp[st][ed].second=min(dp[st][ed].second,tmp2); int tmp3=calc(op[mid],le.second,ri.first);
dp[st][ed].first=max(dp[st][ed].first,tmp3);
dp[st][ed].second=min(dp[st][ed].second,tmp3); int tmp4=calc(op[mid],le.second,ri.second);
dp[st][ed].first=max(dp[st][ed].first,tmp4);
dp[st][ed].second=min(dp[st][ed].second,tmp4);
}
}
}
return dp[l][r].first;
}
int main()
{
scanf("%d",&n);
for(int i=;i<n;i++)
{
int m; char o[];
scanf("%s",o); op[i]=op[n+i]=(o[]=='x');
scanf("%d",&m); nm[i]=nm[n+i]=m;
} for(int i=;i<*n;i++) dp[i][i]=make_pair(nm[i%n],nm[i%n]);
int ans=-INF;
for(int c=;c<n;c++) ans=max(ans,solve(c,c+n-)); vector<int> E;
for(int c=;c<n;c++) if(dp[c][c+n-].first==ans) E.push_back(c+);
sort(E.begin(),E.end());
printf("%d\n",ans);
for(int i=;i<E.size();i++) printf("%d%c",E[i],(i==E.size()-)?'\n':' ');
}

数据:

x  x  t  t  x 

x - t - t - t - x -

t  x  t -

x  t  x  t  t  x  x  x  x  x  x  t  t  x  t  x  x  t  x  x  t  x  x  x  x  x  t  x  x  x 

x  x  x  x - t  x - x - x  t  t - x  t  x  x  t  x  x - x - x  x  t  x  t  x  x  x  t  x  x  x  x  x  x  x - t  x  x - x - t  x  t  x  x  x - t  t - t - x 

POJ 1179 - Polygon - [区间DP]的更多相关文章

  1. IOI 98 (POJ 1179)Polygon(区间DP)

    很容易想到枚举第一步切掉的边,然后再计算能够产生的最大值. 联想到区间DP,令dp[i][l][r]为第一步切掉第i条边后从第i个顶点起区间[l,r]能够生成的最大值是多少. 但是状态不好转移,因为操 ...

  2. POJ 2995 Brackets 区间DP

    POJ 2995 Brackets 区间DP 题意 大意:给你一个字符串,询问这个字符串满足要求的有多少,()和[]都是一个匹配.需要注意的是这里的匹配规则. 解题思路 区间DP,开始自己没想到是区间 ...

  3. poj 1179 Polygon

    http://poj.org/problem?id=1179 Polygon Time Limit: 1000MS   Memory Limit: 10000K Total Submissions:  ...

  4. POJ 1160 经典区间dp/四边形优化

    链接http://poj.org/problem?id=1160 很好的一个题,涉及到了以前老师说过的一个题目,可惜没往那上面想. 题意,给出N个城镇的地址,他们在一条直线上,现在要选择P个城镇建立邮 ...

  5. IOI1998 Polygon [区间dp]

    [IOI1998]Polygon 题意翻译 题目可能有些许修改,但大意一致 多边形是一个玩家在一个有n个顶点的多边形上的游戏,如图所示,其中n=4.每个顶点用整数标记,每个边用符号+(加)或符号*(乘 ...

  6. POJ 1390 Blocks(区间DP)

    Blocks [题目链接]Blocks [题目类型]区间DP &题意: 给定n个不同颜色的盒子,连续的相同颜色的k个盒子可以拿走,权值为k*k,求把所有盒子拿完的最大权值 &题解: 这 ...

  7. poj 2955"Brackets"(区间DP)

    传送门 https://www.cnblogs.com/violet-acmer/p/9852294.html 题意: 给你一个只由 '(' , ')' , '[' , ']' 组成的字符串s[ ], ...

  8. POJ 1159 Palindrome(区间DP/最长公共子序列+滚动数组)

    Palindrome Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 56150   Accepted: 19398 Desc ...

  9. HOJ 1936&POJ 2955 Brackets(区间DP)

    Brackets My Tags (Edit) Source : Stanford ACM Programming Contest 2004 Time limit : 1 sec Memory lim ...

随机推荐

  1. wkhtmlpdf安装以及中文乱码

    见此页http://www.cnblogs.com/day959/p/6652726.html

  2. Xilinx 常用模块汇总(verilog)【04】

    作者:桂. 时间:2018-05-15  13:07:02 链接:http://www.cnblogs.com/xingshansi/p/9040472.html 前言 Xilinx 常用模块汇总(v ...

  3. rinetd 一个linux下的端口转发工具

    inux下使用iptables实现端口转发,配置较为复杂,使用rinetd工具可以实现快速配置和修改端口转发. 例:本机ip:1.1.1.1 需要实现访问本机的8080端口,自动转发到2.2.2.2 ...

  4. JAVA(一)JAVA基础/面向对象基础/高级面向对象

    成鹏致远 | lcw.cnblog.com |2014-01-23 JAVA基础 1.开发环境搭建 JAVA程序的执行流程 JAVA命令->要使用一个*.class文件(类文件)->通过c ...

  5. 一篇文全面了解DevOps:从概念、关键问题、兴起到实现需求

    一篇文全面了解DevOps:从概念.关键问题.兴起到实现需求 转自:一篇文全面了解DevOps:从概念.关键问题.兴起到实现需求 2018-06-06 目前在国外,互联网巨头如Google.Faceb ...

  6. idea git 使用

    第一部  测试  本地git 是否已经成功安装 centos 7 发行版默认已经安装 第二部: 测试 github 连接是否成功,需要输入用户密码 第三部:创建git项目管理两种方式 1. 菜单 VC ...

  7. Python3解《剑指》问题:“遇到奇数移至最前,遇到偶数移至最后”

    [本文出自天外归云的博客园] 看到一个<剑指Offer>上的问题:“遇到奇数移至最前,遇到偶数移至最后.” 我做了两种解法.一种是利用python内置函数,移动过程用了插入法,很简单.另一 ...

  8. golang_elasticsearch 多精确值匹配

    问题 比如要查找属于两种类型的物品,这个时候,term查询就不行了,需要采用terms查询. golang中的用法 看了一下,olivere/elastic 包提供了一个 terms查询,于是高兴的直 ...

  9. T-SQL基础查询——单表查询

    1,查询的顺序 SELECT empid, YEAR(orderdate) AS orderyear, COUNT(*) AS numorders FROM Sales.Orders GROUP BY ...

  10. OAuth 2.0 C# 版

    using System; using System.Collections.Generic; using System.Dynamic; using System.Linq; using Syste ...