ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

P4342 [IOI1998]Polygon

2021-07-18 08:32:02  阅读:174  来源: 互联网

标签:Polygon min int max P4342 合并 区间 include IOI1998


题面

\(IOI\) ?? 一道大水题

题面难以概括,还是去看原题吧

solution

环上 \(dp\) ,断环成链

然后做区间 \(dp\) 板子,枚举断点

这个题唯一的 \(tip\) 就是处理区间合并

因为区间合并有乘,所以有负负得正情况,所以还要维护一个区间最小值

对于合并要考虑一大堆情况,详细看这 题解 P4342 [IOI1998]Polygon

最后可以合并得到两个转移式 (\(g[i][j]\) 为区间最小值,\(f[i][j]\) 为区间最大值)

\(f[i][j]=max(f[i][j],max(f[i][k]×f[k+1][j],max(g[i][k]×g[k+1][j],max(f[i][k]×g[k+1][j],g[i][k]×f[k+1][j]))))\)

\(g[i][j]=min(g[i][j],min(f[i][k]×f[k+1][j],min(g[i][k]×g[k+1][j],min(f[i][k]×g[k+1][j],g[i][k]×f[k+1][j]))))\)

加的合并

\(f[i][j] = max(f[i][j], f[i][k] + f[k + 1][j]);\)

\(g[i][j] = min(g[i][j], g[i][k] + g[k + 1][j]);\)

注意代码输入格式!!

\(code\)

/*
work by:Ariel_
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int N = 150;
int read() {
  int x = 0, f = 1; char c = getchar();
  while(c < '0' || c > '9'){if (c == '-') f = -1;c = getchar();}
  while(c >= '0' && c <= '9') {x = x * 10 + c - '0';c = getchar();}
  return x * f;
}
int a[N], n, f[N][N], g[N][N];
char c[N]; 
int main(){
  scanf("%d\n", &n);
  for (int i = 1; i <= n; i++) {
  	scanf("%c %d", &c[i], &a[i]); getchar();
  	c[i + n] = c[i], a[i + n] = a[i];//断环成链 
  }
  memset(f, -0x3f3f3f3f, sizeof f), memset(g, 0x3f3f3f3f, sizeof g);
  for (int i = 1; i <= (n << 1); i++) f[i][i] = g[i][i] = a[i];
  for (int len = 1; len < n; len++)
  	for (int i = 1, j = i + len; j <= (n << 1); j++, i++) {
  		for (int k = i; k < j; k++) {
  		    if (c[k + 1] == 'x') {
  		    	f[i][j] = max(f[i][j], max(f[i][k] * f[k + 1][j], max(g[i][k] * g[k + 1][j], max(f[i][k] * g[k + 1][j], g[i][k] * f[k + 1][j]))));
  		    	g[i][j] = min(g[i][j], min(f[i][k] * f[k + 1][j], min(g[i][k] * g[k + 1][j], min(f[i][k] * g[k + 1][j], g[i][k] * f[k + 1][j])))); 
			  }	 
			if (c[k + 1] == 't') {
			   f[i][j] = max(f[i][j], f[i][k] + f[k + 1][j]);
			   g[i][j] = min(g[i][j], g[i][k] + g[k + 1][j]);
			}  
		  }
	  }
  int Ans = -0x3f3f3f3f;
  for (int i = 1; i <= n; i++) Ans = max(Ans, f[i][i + n - 1]);
  printf("%d\n", Ans); 
  for (int i = 1;i <= n; i++) if (f[i][i + n - 1] == Ans) printf("%d ",i);
  puts("");
  return 0;
}

标签:Polygon,min,int,max,P4342,合并,区间,include,IOI1998
来源: https://www.cnblogs.com/Arielzz/p/15025798.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有