283. 多边形

2024-05-11 00:58
文章标签 多边形 283

本文主要是介绍283. 多边形,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

算法分析:
初看起来,就是简单的区间dp,于是很顺利打出来,结果有些点过不了。百思不得其解。下面是初始代码。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
int n, dotval[110], f[110][110];
char edgval[110];
int main()  // 没有考虑负数,不全面  
{scanf("%d", &n);//使用格式化输入scanf混读%c和%d有点问题,数据不大,可以用cin  for (int i = 1; i <= n; ++i) {cin>>edgval[i]>>dotval[i];edgval[i+n] = edgval[i];dotval[i+n] = dotval[i]; } // 将环拆成链后,每个点前面的那条边是属于该点的边 n *= 2;memset(f, 0xcf, sizeof(f));for (int i = 1; i <= n; ++i)  f[i][i] = dotval[i];for (int len = 2; len <= n; ++len)for (int i = 1; i < n; ++i){int j = i + len - 1;if (j > n) continue;for (int k = i; k < j; ++k){int tem;if (edgval[k+1] == 't') tem = f[i][k] + f[k+1][j];else tem = f[i][k] * f[k+1][j];f[i][j] = max(f[i][j], tem);}}int ans = -1e9;n /= 2;for (int i = 1; i <= n; ++i)if (f[i][i+n-1] > ans) 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);printf("\n");return 0;
}

看书上的讲解,原来是没有考虑负数的问题。状态 f [ i ] [ j ] f[i][j] f[i][j],如果是加号,没有问题。但如果是乘号的话,是不能简单地有 f [ i ] [ k ] ∗ f [ k + 1 ] [ j ] f[i][k]*f[k+1][j] f[i][k]f[k+1][j]转移过来的。因为两个负数相乘也许是一个超过两个最大值的数。状态 f m a x [ i ] [ j ] f_max[i][j] fmax[i][j]表示区间 [ i , j ] [i,j] [i,j]的最大值, g m i n [ i ] [ j ] g_min[i][j] gmin[i][j]表示最小值。则对于乘号来讲:
f m a x [ i ] [ j ] = m a x ( f m a x [ i ] [ k ] ∗ f m a x [ k + 1 ] [ j ] , f m a x [ i ] [ k ] ∗ g m i n [ k + 1 ] [ j ] , g m i n [ i ] [ k ] ∗ f m a x [ k + 1 ] [ j ] , g m i n [ i ] [ k ] ∗ g m i n [ k + 1 ] [ j ] ) fmax[i][j] = max(fmax[i][k]*fmax[k+1][j],fmax[i][k]*gmin[k+1][j],gmin[i][k]*fmax[k+1][j],gmin[i][k]*gmin[k+1][j]) fmax[i][j]=max(fmax[i][k]fmax[k+1][j],fmax[i][k]gmin[k+1][j],gmin[i][k]fmax[k+1][j],gmin[i][k]gmin[k+1][j])
g m i n [ i ] [ j ] = m i n ( f m a x [ i ] [ k ] ∗ f m a x [ k + 1 ] [ j ] , f m a x [ i ] [ k ] ∗ g m i n [ k + 1 ] [ j ] , g m i n [ i ] [ k ] ∗ f m a x [ k + 1 ] [ j ] , g m i n [ i ] [ k ] ∗ g m i n [ k + 1 ] [ j ] ) gmin[i][j] = min(fmax[i][k]*fmax[k+1][j],fmax[i][k]*gmin[k+1][j],gmin[i][k]*fmax[k+1][j],gmin[i][k]*gmin[k+1][j]) gmin[i][j]=min(fmax[i][k]fmax[k+1][j],fmax[i][k]gmin[k+1][j],gmin[i][k]fmax[k+1][j],gmin[i][k]gmin[k+1][j])

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
int n, dotval[110], f_max[110][110], g_min[110][110];
char edgval[110];
int main()
{scanf("%d", &n);//使用格式化输入scanf混读%c和%d有点问题,数据不大,可以用cin  for (int i = 1; i <= n; ++i) {cin>>edgval[i]>>dotval[i];edgval[i+n] = edgval[i];dotval[i+n] = dotval[i]; } // 将环拆成链后,每个点前面的那条边是属于该点的边 n *= 2;memset(f_max, 0xcf, sizeof(f_max));  // 极小值 memset(g_min, 0x3f, sizeof(g_min));  // 极大值  for (int i = 1; i <= n; ++i)  f_max[i][i] = g_min[i][i] = dotval[i];for (int len = 2; len <= n; ++len)for (int i = 1; i < n; ++i){int j = i + len - 1;if (j > n) continue;for (int k = i; k < j; ++k){int temmax = -1e9, temmin = 1e9;if (edgval[k+1] == 't'){f_max[i][j] = max(f_max[i][j], f_max[i][k] + f_max[k+1][j]);g_min[i][j] = min(g_min[i][j], g_min[i][k] + g_min[k+1][j]);}else{temmax = max(temmax, f_max[i][k] * f_max[k+1][j]);temmax = max(temmax, f_max[i][k] * g_min[k+1][j]);temmax = max(temmax, g_min[i][k] * f_max[k+1][j]);temmax = max(temmax, g_min[i][k] * g_min[k+1][j]);temmin = min(temmin, f_max[i][k] * f_max[k+1][j]);temmin = min(temmin, f_max[i][k] * g_min[k+1][j]);temmin = min(temmin, g_min[i][k] * f_max[k+1][j]);temmin = min(temmin, g_min[i][k] * g_min[k+1][j]);f_max[i][j] = max(f_max[i][j], temmax);g_min[i][j] = min(g_min[i][j], temmin);}}}int ans = -1e9;n /= 2;for (int i = 1; i <= n; ++i)if (f_max[i][i+n-1] > ans) ans = f_max[i][i+n-1];printf("%d\n", ans);for (int i = 1; i <= n; ++i)if (f_max[i][i+n-1] == ans) printf("%d ", i);printf("\n");return 0;
}

总结与反思:

  1. 还是审题不清。没有注意到负数的问题。
  2. 破环成链是解决环上问题的经典方法。

这篇关于283. 多边形的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/978055

相关文章

Codeforces Round #113 (Div. 2) B 判断多边形是否在凸包内

题目点击打开链接 凸多边形A, 多边形B, 判断B是否严格在A内。  注意AB有重点 。  将A,B上的点合在一起求凸包,如果凸包上的点是B的某个点,则B肯定不在A内。 或者说B上的某点在凸包的边上则也说明B不严格在A里面。 这个处理有个巧妙的方法,只需在求凸包的时候, <=  改成< 也就是说凸包一条边上的所有点都重复点都记录在凸包里面了。 另外不能去重点。 int

【Godot4.3】多边形的斜线填充效果基础实现

概述 图案(Pattern)填充是一个非常常见的效果。其中又以斜线填充最为简单。本篇就探讨在Godot4.3中如何使用Geometry2D和CanvasItem的绘图函数实现斜线填充效果。 基础思路 Geometry2D类提供了多边形和多边形以及多边形与折线的布尔运算。按照自然的思路,多边形的斜线填充应该属于“多边形与折线的布尔运算”范畴。 第一个问题是如何获得斜线,这条斜线应该满足什么样

模拟退火判断一个圆是否可以放在一个多边形内

/*给定n个点的一个多边形,一个圆的半径,判断圆是否可以放在多边形里*//* ***********************************************Author :rabbitCreated Time :2014/7/3 22:46:38File Name :2.cpp**********************************************

CF #283 (Div. 2) B.(字符串好多坑)

题目链接:http://codeforces.com/contest/496/problem/B 解题思路: 首先明确可以暴力,写一个add函数和shift函数。然后给一个循环值cnt,做cnt次循环即可,每次取两种情况的最小值入字符串数组,最后排下序,输出最小的字符串。 这个cnt很不好控制,我也是WA了几次才估计出来的······· 接下来说说奇葩的数据: Input: 1

CF #283 (Div. 2) A.(屏蔽数组元素)

题目链接:http://codeforces.com/contest/496/problem/A 解题思路: n不是很大,所以暴力。每次屏蔽掉a[ i ]中的一个元素,注意头和尾不能屏蔽。屏蔽后当i == j 时做特殊处理,即cnt = a[ i+ 1 ] - a[ i - 1 ]。最后更新最小值即可。 完整代码: #include <functional>#includ

利用向量积(叉积)计算三角形的面积和多边形的面积(hdu2036)

开始撸计算几何题目了。。。。。。。 预备知识:叉乘求多边形面积 参考证明资料: 公式证明: http://www.cnblogs.com/xiexinxinlove/p/3708147.html 高中知识: http://wenku.baidu.com/view/867e6edfad51f01dc281f11a.html #include<stdio.h>#inclu

HDU 2036 求多边形面积

题目: http://acm.hdu.edu.cn/showproblem.php?pid=2036 对用(按逆时针排列)描述的多边形,其面积为: 若按顺时针排列,取负数即可。 资料链接: http://zh.wikipedia.org/wiki/%E5%A4%9A%E8%BE%B9%E5%BD%A2 不知道这公式是咋推导的,网上找不到,先留着。 #

[LeetCode] 283. Move Zeroes

题:https://leetcode.com/problems/move-zeroes/submissions/1 题目 Given an array nums, write a function to move all 0’s to the end of it while maintaining the relative order of the non-zero elements. Ex

图形几何-如何将凹多边形分解成若干个凸多边形

凹多边形的概念         凹多边形是指至少有一个内角大于180度的多边形。与之相对,凸多边形的所有内角均小于或等于180度,且任意两点之间的连线都完全位于多边形内部。将凹多边形分解成若干个凸多边形是计算几何中的一个重要问题。 分解原理         将凹多边形分解为凸多边形的基本原理是通过绘制对角线来消除凹角。对角线是连接多边形两个非相邻顶点的线段。通过适当选择对角线,可以将凹多边形

Codeforces 283. B. Cow Program记忆化搜索

output standard output Farmer John has just given the cows a program to play with! The program contains two integer variables, x and y, and performs the following operations on a sequence a1, a2, ..