【POJ1179】Polygon 区间DP
这道题是典型的环形石子归并模型,破环成链后时间复杂度为\(O(n^3)\)
不过,因为题目中所给的数字可能是负数,仅仅记录区间内合并之后的最大值并不满足动态规划的最优子结构性质。因此,还需要额外记录下区间合并后的最小值,由最小值和最大值即可组合出整个区间的最大值。
代码如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn=110;
char s[2];
int n,num[maxn],head[maxn];//0->+ 1->*
struct node{
long long mx,mi;
}dp[maxn][maxn];
vector<int> v;
void read_and_parse(){
scanf("%d",&n);
for(int i=1;i<=n;i++){//破环成链
scanf("%s%d",s,&num[i]);
if(s[0]=='t')head[i]=0;
else head[i]=1;
num[i+n]=num[i],head[i+n]=head[i];
}
for(int i=1;i<=n;i++){//初始化
dp[i][i].mx=dp[i+n][i+n].mx=num[i];
dp[i][i].mi=dp[i+n][i+n].mi=num[i];
}
}
const int inf=0x3f3f3f3f;
void solve(){
for(int len=2;len<=n;len++){
for(int l=1;l<=2*n-len+1;l++){
int r=l+len-1;
dp[l][r].mi=inf,dp[l][r].mx=-inf;
for(int k=l;k<r;k++){
if(head[k+1]){
dp[l][r].mx=max(dp[l][r].mx,dp[l][k].mi*dp[k+1][r].mi);
dp[l][r].mx=max(dp[l][r].mx,dp[l][k].mx*dp[k+1][r].mx);
dp[l][r].mi=min(dp[l][r].mi,dp[l][k].mx*dp[k+1][r].mx);
dp[l][r].mi=min(dp[l][r].mi,dp[l][k].mi*dp[k+1][r].mi);
dp[l][r].mi=min(dp[l][r].mi,dp[l][k].mx*dp[k+1][r].mi);
dp[l][r].mi=min(dp[l][r].mi,dp[l][k].mi*dp[k+1][r].mx);
}
else{
dp[l][r].mx=max(dp[l][r].mx,dp[l][k].mx+dp[k+1][r].mx);
dp[l][r].mi=min(dp[l][r].mi,dp[l][k].mi+dp[k+1][r].mi);
}
}
}
}
long long ans=-inf;
for(int i=1;i<=n;i++){
if(dp[i][i+n-1].mx>ans){
v.clear(),v.push_back(i);
ans=dp[i][i+n-1].mx;
}
else if(dp[i][i+n-1].mx==ans)
v.push_back(i);
}
printf("%lld\n",ans);
for(int i=0;i<v.size();i++)
printf("%d%c",v[i],i==v.size()-1?'\n':' ');
}
int main(){
read_and_parse();
solve();
return 0;
}
【POJ1179】Polygon 区间DP的更多相关文章
- POJ1179 Polygon 区间DP
题目大意: 多边形游戏,有N个顶点的多边形,3 <= N <= 50 ,多边形有N条边,每个顶点中有一个数字(可正可负),每条边上或者是“+”号,或者是“*”号.边从1到N编号,首先选择一 ...
- POJ 1179 - Polygon - [区间DP]
题目链接:http://poj.org/problem?id=1179 Time Limit: 1000MS Memory Limit: 10000K Description Polygon is a ...
- IOI1998 Polygon [区间dp]
[IOI1998]Polygon 题意翻译 题目可能有些许修改,但大意一致 多边形是一个玩家在一个有n个顶点的多边形上的游戏,如图所示,其中n=4.每个顶点用整数标记,每个边用符号+(加)或符号*(乘 ...
- IOI 98 (POJ 1179)Polygon(区间DP)
很容易想到枚举第一步切掉的边,然后再计算能够产生的最大值. 联想到区间DP,令dp[i][l][r]为第一步切掉第i条边后从第i个顶点起区间[l,r]能够生成的最大值是多少. 但是状态不好转移,因为操 ...
- poj1179多边形——区间DP
题目:http://poj.org/problem?id=1179 区间DP,值得注意的是有负值,而且有乘法,因此可能会影响最大值: 注意memset中写-1仅仅是-1,-2才是一个很小的负数: 最后 ...
- 【IOI1998】Polygon 区间DP
题意翻译 题目可能有些许修改,但大意一致 多边形是一个玩家在一个有n个顶点的多边形上的游戏,如图所示,其中n=4.每个顶点用整数标记,每个边用符号+(加)或符号*(乘积)标记. 第一步,删除其中一条边 ...
- [IOI1998] Polygon (区间dp,和石子合并很相似)
题意: 给你一个多边形(可以看作n个顶点,n-1条边的图),每一条边上有一个符号(+号或者*号),这个多边形有n个顶点,每一个顶点有一个值 最初你可以把一条边删除掉,这个时候这就是一个n个顶点,n-2 ...
- poj1179 环形+区间dp
因为要用到模,所以左起点设置为0比较好 #include<iostream> #include<cstdio> #include<cstring> #define ...
- 「IOI1998」「LuoguP4342」Polygon(区间dp
P4342 [IOI1998]Polygon - 洛谷 题意翻译 题目可能有些许修改,但大意一致 多边形是一个玩家在一个有n个顶点的多边形上的游戏,如图所示,其中n=4.每个顶点用整数标记,每个边用符 ...
随机推荐
- BugkuCTF SQL注入1
前言 写了这么久的web题,算是把它基础部分都刷完了一遍,以下的几天将持续更新BugkuCTF WEB部分的题解,为了不影响阅读,所以每道题的题解都以单独一篇文章的形式发表,感谢大家一直以来的支持和理 ...
- MRT与MRTS工具官宣退休,推荐使用HEG
今天错误的删除搞丢了之前下载的MRT与MRTS工具,浏览Modis官网下载时发现找不到了,后来在其官网上发现了这则通知,原来早已停止更新的MRT这次彻底退修了.通知原文如下~~~ The downlo ...
- Openstack部署踩坑
第一周: 使用kola部署Openstack,vip_address有问题,双网上也不行,就是部署不了,但all-in-one却可以,可是节点不会加. 第二周: 使用Packstack部署Openst ...
- require.ensure的用法;异步加载-代码分割;
webpack异步加载的原理 webpack ensure相信大家都听过.有人称它为异步加载,也有人说做代码切割,那这 个家伙到底是用来干嘛的?其实说白了,它就是把js模块给独立导出一个.js文件的, ...
- 个人对vuex的表象理解(笔记)
一个东西,首先要知道为什么用它,为什么要vuex,官方解释为了解决繁杂事件订阅和广播,那么事件的$dispatch,$on,怎么就复杂了?许多人是不是感觉后者还挺简单的,对的 如果简单小型项目,那么不 ...
- Linux环境C程序设计
Linux基础 常用shell命令 命令 说明 命令 说明 man 查看联机帮助 ls 查看目录及文件列表 cp 复制目录或文件 mv 移动目录或文件 cd 改变文件或目录 rm 删除文件或目录 mk ...
- jquery打印页面(jquery.jqprint)
使用jquery进行打印时,所需js包:jquery-1.4.4.min.js.jquery.jqprint-0.3.js 但如果使用高版本的jquery(jquery-1.9.1.min.js)时, ...
- “数学口袋精灵”App的第三个Sprint计划(总结与团队感悟)----开发日记
第三阶段Sprint完成情况: 我们的"数学口袋精灵"App已经完成了,该app能随机产生多种形式的算式,比如带括号的,分数四则运算,混合运算,阶乘等,通过游戏形式让用户乐在其中. ...
- Lucene源码
看Lucene源码必须知道的基本概念 终于有时间总结点Lucene,虽然是大周末的,已经感觉是对自己的奖励,毕竟只是喜欢,现在的工作中用不到的.自己看源码比较快,看英文原著的技术书也很快.都和语言有很 ...
- CSS响应式网站开发
<html> <head> //当设备屏幕最大宽度小于1024px时加载如下CSS内容 @media screen and (max-width: 1024px){ ...