uva 1331 - Minimax Triangulation(dp)

题目链接:uva 1331 - Minimax Triangulation

题目大意:按照顺时针或者逆时针的顺序给出多边的点,要将这个多边形分解成n-2个三角形,要求使得这些三角行中面积最大的三角形面积尽量小,求最小值。

解题思路:状态很好想,dp[i][j]表示从第i个点到第j个点,划分成j-i-1个三角形的最优解,然后每次转移时,枚举长度和左边界始点,那么根据长度和左边界点就可以知道右边界点,然后枚举左边界和右边界中间的点k,dp[i][j] = min(dp[i][j], max(max(dp[i][k], dp[k][j]), Area(i, k, j)).但是有一个问题,即i,k,j三点围成的三角形是否符合要求,判断的条件即为是否存在除i,k,j三点外的一点位于三角形中,有面积法判断。

然后其实我还一直纠结说凹多边形的时候怎么处理掉得,如图

BCD的组成的三角形式合法的,但是后来想了想,虽然BCD组成的三角形是合法的,但是不会影响到最后的答案。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>

using namespace std;
const int N = 100;
const double INF = 0x3f3f3f3f3f3f;
const double eps = 1e-9;

struct point {
	double x, y;
	void get() {
		scanf("%lf%lf", &x, &y);
	}
}p[N];

int n;
double dp[N][N];

double area (point a, point b, point c) {
	return fabs((b.x-a.x)*(c.y-a.y) - (c.x-a.x)*(b.y-a.y))/2;
}

bool judge (int a, int b, int c) {
	double cur = area(p[a], p[b], p[c]);
	for (int i = 0; i < n; i++) {
		if (i == a || i == b || i == c)
			continue;
		double tmp = area(p[a], p[b], p[i]) + area(p[b], p[c], p[i]) + area(p[c], p[a], p[i]);
		if (fabs(tmp - cur) < eps)
			return false;
	}
	return true;
}

double solve () {
	for (int i = 0; i < 2; i++) {
		for (int j = 0; j < n; j++)
			dp[j][(j+i)%n] = 0;
	}

	for (int i = 0; i < n; i++)
		dp[i][(i+2)%n] = area(p[i], p[(i+1)%n], p[(i+2)%n]);

	for (int k = 3; k < n; k++) {

		for (int i = 0; i < n; i++) {
			int t = (i + k) % n;
			dp[i][t] = INF;
			for (int j = (i+1)%n; j != t; j = (j+1)%n) {
				if (judge(i, t, j))
					dp[i][t] = min(dp[i][t], max(max(dp[i][j], dp[j][t]), area(p[i], p[j], p[t])));
			}
		}
	}

	double ans = INF;
	for (int i = 0; i < n; i++)
		ans = min (ans, dp[i][(i+n-1)%n]);
	return ans;
}

int main () {
	int cas;
	scanf("%d", &cas);
	while (cas--) {
		scanf("%d", &n);
		for (int i = 0; i < n; i++)
			p[i].get();

		printf("%.1lf\n", solve());
	}
	return 0;
}

uva 1331 - Minimax Triangulation(dp)

时间: 2024-08-19 10:59:36

uva 1331 - Minimax Triangulation(dp)的相关文章

UVA 1331 Minimax Triangulation 区间DP

区间DP: 将一个多边形三角剖分,让可以得到的最大三角形的面积最小 dp[i][j]表示从i点到j点的最优值,枚举中间点k dp[i][j]=min(dp[i][j],max(area(i,j,k),max(dp[i][k],dp[k][j]))); 注意如果中间三角形i-j-k中有其他的点,这样的三角形是不可以剖分的 Minimax Triangulation Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld

Uva 1331 - Minimax Triangulation(最优三角剖分 区间DP)

题目大意:按照顺时针或者逆时针的顺序给出多边的点,要将这个多边形分解成n-2个三角形,要求使得这些三角行中面积最大的三角形面积尽量小,求最小值. 思路:用区间DP可以很方便解决,多边形可能是凹边形,注意剖分的三角形必须在多边形内部,所以可以去掉剖分的三角形中包含其他点,但是其他的在多边形外部的三角形没想到其他方法去除,却ac了,不懂为何 // Accepted C++ 0.042 #include<cstdio> #include<iostream> #include<alg

1331 - Minimax Triangulation (区间DP+几何)

题目链接:1331 - Minimax Triangulation 题意:按顺序给定一些点,把这些点分割为n - 2个三角形,代价为最大三角形面积,求代价最小 思路:区间DP,dp[i][j]代表一个区间内,组成的情况,枚举k,dp[i][j] = min(max(dp[i][k],dp[k][j], area(i, j, k)),area代表i.j.k三点构成的三角形面积,然后判断该三角形内有没其他点即可 代码: #include <stdio.h> #include <string.

[UVA 12589]Learning Vector[DP]

题目链接:[UVA 12589]Learning Vector[DP] 题意分析:给出n个矢量,从中选择k个,以坐标原点为起点,收尾相连,问:这样的k个周围相连矢量与x轴围成图形的最大面积的两倍是多少? 解题思路:考虑状态:dp[id][pick][h]代表到第id个矢量为止,选择pick个矢量离最大面积还差多少,h为当前图形最右端高度.具体转移看代码. 这里着重说一下为什么要对这些矢量按斜率进行排序: 首先,整个求解过程其实就是在暴力枚举这些向量的组合,只不过采用了记忆化搜索优化. 其次,对于

Uva 12018 Juice Extractor dp

题目链接:点击打开链接 题意: 切水果游戏 给出n个水果 水果出现在屏幕上的时间的区间 1.每次切会把屏幕上所有水果切完 2.当同时切3个或以上时计分,分数为切的水果个数 3.不能遗漏水果 问最高得分 dp[i] 表示 最后一次切第i个的得分. #include<stdio.h> #include<algorithm> #include<string.h> #include<iostream> using namespace std; #define N 1

uva 11578 - Situp Benches(dp+输出路径)

题目连接:uva 11578 - Situp Benches 题目大意:健身房有两个仪器,初始角度为10度,每次有人使用需要交15元,每调10度需要花费10元,现在有n个人,给出每个人使用仪器的顺序和角度,保证不会同时有大于2个人序号一样,求最小花费,并且输出每个人分别使用哪一个仪器,并且所有人使用结束后,要将仪器调回10度. 解题思路:dp[i][x][y]表示第i个人,一个仪器为x,另一个仪器为y的情况,path[i][x][y]记录的是它的前一个状态,[0]为前一个仪器的夹角,[1]为另一

uva 10269 最短路+dp

题意:有a个村庄.b个城镇, 编号分别为:1-a , a+1--a+b . 有双神奇的鞋,可以瞬时移动,可以使用k次,每次可以移动L , 但穿这双鞋的时候,不能经过城镇 , 问:从a+b 到 1 最短距离是多少? 刚开始看这个题时 , 一点思路都没有 , dp类型的题目做得太少了. 解法:进行状态压缩, 用点+使用鞋子的次数 , 来表示一个状态 , d[i][k] , 表示到 点 i 使用 k 次鞋子的最短距离是多少. 但要先进行初始化 , 求任意点之间不经过城镇的最短距离 , 用floyd算法

uva 10671 - Grid Speed(dp)

题目链接:uva 10671 - Grid Speed 题目大意:给出N,表示在一个N*N的网格中,每段路长L,现在给出h,v的限制速度,以及起始位置sx,sy,终止位置ex,ey,时间范围st,et,车只走最短路,问说在范围内最快到达和耗油量最小的情况下时间和耗油量. 解题思路:dp[x][y][t]表示在x,y这一点,时间为t的耗油量最小为dp[x][y][t],vis[x][y][t]表示该情况是否可达.dx,dy表示由起点向终点移动的方向.因为时间为L?60v, 因为v是5的倍数,并且小

UVA 1559 - Nim(博弈dp)

UVA 1559 - Nim 题目链接 题意:一开始有s个石子,2n个人轮流取石子,每个人有个最大能取数目,2n个人奇数一队,偶数一队,取到最后一个石子的队输,问谁赢 思路:记忆化搜索,每个人取的时候对应的后继状态如果有一个必败态,则该状态为必胜态,如果都是必胜态,则该状态为必败态 代码: #include <stdio.h> #include <string.h> int n, s, m[25], dp[25][10005]; int dfs(int now, int state