HDU 5928 DP 凸包graham
给出点集,和不大于L长的绳子,问能包裹住的最多点数。
考虑每个点都作为左下角的起点跑一遍极角序求凸包,求的过程中用DP记录当前以j为当前末端为结束的的最小长度,其中一维作为背包的是凸包内侧点的数量。也就是 dp[j][k]代表当前链末端为j,其内部点包括边界数量为k的最小长度。这样最后得到的一定是最优的凸包。
然后就是要注意要dp[j][k]的值不能超过L,每跑一次凸包,求个最大的点数量就好了。
和DP结合的计算几何题,主要考虑DP怎么搞
/** @Date : 2017-09-27 17:27:02
* @FileName: HDU 5928 DP 凸包graham.cpp
* @Platform: Windows
* @Author : Lweleth (SoungEarlf@gmail.com)
* @Link : https://github.com/
* @Version : $Id$
*/
#include <bits/stdc++.h>
#define LL long long
#define PII pair<int ,int>
#define MP(x, y) make_pair((x),(y))
#define fi first
#define se second
#define PB(x) push_back((x))
#define MMG(x) memset((x), -1,sizeof(x))
#define MMF(x) memset((x),0,sizeof(x))
#define MMI(x) memset((x), INF, sizeof(x))
using namespace std; const int INF = 0x3f3f3f3f;
const int N = 1e5 + 20;
const double eps = 1e-8; struct point
{
double x, y;
point() {}
point(double _x, double _y)
{
x = _x, y = _y;
}
point operator -(const point &b) const
{
return point(x - b.x, y - b.y);
}
double operator *(const point &b) const
{
return x * b.x + y * b.y;
}
double operator ^(const point &b) const
{
return x * b.y - y * b.x;
}
bool operator < (const point b)const
{
return (x * b.y - y * b.x) > 0;
}
}; double xmult(point p1, point p2, point p0)
{
return (p1 - p0) ^ (p2 - p0);
} double distc(point a, point b)
{
return sqrt((double)((b - a) * (b - a)));
} point orig;
int cmp(point a, point b)//以p[0]基准 极角序排序
{
int t = xmult(a, b, orig);
if(t > 0)
return 1;
if(t == 0)
return distc(a, orig) < distc(b, orig);
if(t < 0)
return 0;
} int cmp1(point a, point b, point orig)//
{
int t = xmult(a, b, orig);
if(t > 0)
return 1;
if(t == 0)
return distc(a, orig) < distc(b, orig);
if(t < 0)
return 0;
} double dp[110][110];
point p[110]; int main()
{
int T;
cin >> T;
int icas = 0;
while(T--)
{
int n;
double l;
scanf("%d%lf", &n, &l);
for(int i = 1; i <= n; i++)
{
double x, y;
scanf("%lf%lf", &x, &y);
p[i] = point(x, y);
}
int cnt = 0;
for(int org = 1; org <= n; org++)//枚举左下点作为起点
{
vector<point>q;
for(int i = 1; i <= n; i++)
if(p[i].y >= p[org].y && i != org)//下方的点忽略
q.PB(p[i]);
orig = p[org];
sort(q.begin(), q.end(), cmp);//极角排序
memset(dp, 0x7f, sizeof(dp));//dp[j][k]代表当前凸包以j为终点,内部点数量为k的最小长度 for(int i = 0; i < q.size(); i++)//暴力使用卷包裹法
{
dp[i][1] = distc(q[i], orig);
for(int j = i + 1; j < q.size(); j++)
{
double dis = distc(q[j] , q[i]);//向量差
if(dp[i][1] + dis > l)//通过DP值排除不必要点
continue;
int t = 1;
for(int k = i + 1; k < j; k++)//计算含边界内侧点数量
if(cmp1(q[j], q[k], q[i]))
t++;
for(int k = 1; k <= i + 1 + t && k <= j + 1; k++)//以点数量作为背包转移
if(k - t >= 0 && dp[i][k - t] + dis <= l)
dp[j][k] = min(dp[i][k - t] + dis, dp[j][k]);
}
for(int k = 1; k <= n - 1; k++)//
if(dp[i][k] + distc(q[i], orig) <= l)
cnt = max(cnt, k);
}
}
printf("Case #%d: %d\n", ++icas, cnt + 1);
}
return 0;
}
HDU 5928 DP 凸包graham的更多相关文章
- [hdu contest 2019-07-29] Azshara's deep sea 计算几何 动态规划 区间dp 凸包 graham扫描法
今天hdu的比赛的第一题,凸包+区间dp. 给出n个点m个圆,n<400,m<100,要求找出凸包然后给凸包上的点连线,连线的两个点不能(在凸包上)相邻,连线不能与圆相交或相切,连线不能相 ...
- HDU 4946 共线凸包
题目大意: 一些点在一张无穷图上面,每个点可以控制一些区域,这个区域满足这个点到达这个区域的时间严格小于其他点.求哪些点能够控制无穷面积的区域. 题目思路: 速度小的控制范围一定有限. 速度最大当且仅 ...
- hdu 3016 dp+线段树
Man Down Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total S ...
- Surround the Trees---hdu1392(凸包GraHam模板)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1392 题意:有n棵树,每棵树有一个坐标,想用一些绳子把这些树包含起来,求需要绳子的长度: 就是求凸包的 ...
- hdu 1348 (凸包求周长)
链接:http://acm.hdu.edu.cn/showproblem.php?pid=1348 Wall Time Limit: 2000/1000 MS (Java/Others) Mem ...
- HDU 4978 计算 凸包
有以无限间隔$D$的水平线分割的平面,在上面随机投下一个圆,圆中有一些点,点之间两两成一条线段,问随机投下至少有一条线段于平行线相交的概率. 以下是不严(luan)谨(lai)的思路. 首先都知道对于 ...
- HDU 1069 dp最长递增子序列
B - Monkey and Banana Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I6 ...
- HDU 1160 DP最长子序列
G - FatMouse's Speed Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64 ...
- hdu 4826(dp + 记忆化搜索)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4826 思路:dp[x][y][d]表示从方向到达点(x,y)所能得到的最大值,然后就是记忆化了. #i ...
随机推荐
- Head First Java & static
- vue 选项卡(转载)
!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta http-e ...
- linux yum 下载至本地及使用本地缓存安装包
由于网络安全的原因,服务器不允许上公网,有2种方案,解决这个问题 1.搭建yum服务器2.使用yum下载缓存进行封装,然后使用缓存安装 这里讲讲使用yum缓存封装 一.下载指定包及相关依赖 yum i ...
- [总结] Visual Studio 报价已经对比
来源微软官方网站 对比 https://visualstudio.microsoft.com/zh-hans/vs/compare/?rr=https%3A%2F%2Fwww.ithome.com%2 ...
- php连接池 php–cp
原文地址:http://blog.sina.com.cn/s/blog_9eaa0f400102v9fd.html 数据库连接池php-cp介绍时间 2015-01-23 11:53:05 数据库连接 ...
- SQL中字符串截取、连接、替换等函数的用法
一.SQL中SUBSTRING函数的用法1.功能:返回字符.二进制.文本或图像表达式的一部分2.语法:SUBSTRING ( expression, start, length )3.QL 中的 su ...
- Code Blocks中配置OpenGL
使用的文件:我的CSDN资源共享 将glut.h文件放到MinGw\include\GL目录下面 将glut32.dll文件放到C:\windows\system32目录下面(如果是64位操作系统的话 ...
- Tomcat 启动流程
- Android CollapsingToolbarLayout
第一次看到这种用户体验是在Google Play Store App的应用详情的Activity中. 大的Banner图,能第一时间吸引用户的眼球,用不一样的Banner大图更具个性化的展示内容.图总 ...
- Gson获取json串中的key-value
1.依赖包 <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson& ...