UVA - 10641 Barisal Stadium (DP + 几何)

该博客讨论了UVA 10641问题,即如何用最少的光源费用照亮一个包含n条边的凸多边形。博主分析了问题涉及的几何和动态规划知识,包括向量叉乘判断方向、光源覆盖范围计算以及动态规划的状态转移。还提供了相关参考链接和解决环问题的方法。
摘要由CSDN通过智能技术生成

问题

平面上,n(n<=30)条边凸多边形,外部有m(m<=1000)个光源,光源可以照亮一些边,每个光源有坐标和费用,求照亮整个凸多边形所有边的最小光源费用

分析

这题涉及到了几何和环的内容,比较难
参考:
https://www.2cto.com/kf/201410/344967.html
https://blog.csdn.net/keshuai19940722/article/details/25080831
向量叉乘:
如何判断两个向量之间夹角是顺时针还是逆时针?
利用平面向量的叉乘,a,b是平面向量,a = (x1,y1) b = (x2,y2)
a×b = x1y2 - x2y1,若结果为正,则向量b在a的逆时针方向
否则,b在a的顺时针方向
若结果为0,则a与b共线
注:两向量之间夹角以小于180度计算
计算一个光源可以覆盖的点的范围[left,right]
1.可以求出凸多边形的几何中心,然后对于每条边计算和光源的是否在同一侧,在同一侧就不能照亮,在异侧就可以照亮
2.可以计算光源和两个相邻点之间的向量A,B是顺时针还是逆时针,因为输入时逆时针,所以如果AB之间是顺时针,那么就可以照亮这两个点
dp[i][i+j]表示照亮[i,i+j]这些点的最小消耗,i=0->n-1,j=0->n-1,dp更新使用刷表法
dp更新状态 使用刷表法,用dp[i][i+j]状态加一个灯 更新dp[i][cur]
dp[cur]=min(dp[cur],dp[t]+light[k].c)

因为将数组长度乘以2,巧妙处理了环的问题,也引起了一些问题,所以遍历i来弥补,定了起点之后,就会有一些点不能全部在换的技术范围内,所以有问题,那就遍历起点来弥补
for(int i=0;i<n;++i)
dp[now]是指从i到now所有点都被灯光照亮所需要的费用,所以就是从起点i出发,然后一次寻找能够接续的灯光。j和x的循环遍历起到了动态规划的作用,计算dp

环:[0-n],,n,0重合,数组[0 - 2n-1]

我的理解:i是为了能够涵盖所有的取值情况,因为有些点的覆盖范围超出了n,比如说灯光A=【n-1,2n-3】这种,跨度很大,对于i=0来说,它的范围是【0,n-1】是一个环,那么计算时他就只能把A的n-1计算进来,A的长度对他来说是1,就不是很好的选择,但是实际上A的范围很广,可能是一个好的选择,所以要遍历i,这样环的每一个侧面都能被考虑到,然后再统一对比,这就是我的理解

备注:开始没注意,INF设为0x7f7f7f7f,结果溢出了
#include<iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int maxn=50,maxm=1005,Inf=0x3f3f3f3f;
const double eps=1e-6;
int N,M,dp[2*maxn]; //成环,两倍数组
double x,y;
bool flag[maxn];
struct Point{
   
    double x,y;
    Point(double x=0,double y=0):x(x),</
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值