给出点集,和不大于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的更多相关文章

  1. [hdu contest 2019-07-29] Azshara's deep sea 计算几何 动态规划 区间dp 凸包 graham扫描法

    今天hdu的比赛的第一题,凸包+区间dp. 给出n个点m个圆,n<400,m<100,要求找出凸包然后给凸包上的点连线,连线的两个点不能(在凸包上)相邻,连线不能与圆相交或相切,连线不能相 ...

  2. HDU 4946 共线凸包

    题目大意: 一些点在一张无穷图上面,每个点可以控制一些区域,这个区域满足这个点到达这个区域的时间严格小于其他点.求哪些点能够控制无穷面积的区域. 题目思路: 速度小的控制范围一定有限. 速度最大当且仅 ...

  3. hdu 3016 dp+线段树

    Man Down Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

  4. Surround the Trees---hdu1392(凸包GraHam模板)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1392 题意:有n棵树,每棵树有一个坐标,想用一些绳子把这些树包含起来,求需要绳子的长度: 就是求凸包的 ...

  5. hdu 1348 (凸包求周长)

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=1348 Wall Time Limit: 2000/1000 MS (Java/Others)    Mem ...

  6. HDU 4978 计算 凸包

    有以无限间隔$D$的水平线分割的平面,在上面随机投下一个圆,圆中有一些点,点之间两两成一条线段,问随机投下至少有一条线段于平行线相交的概率. 以下是不严(luan)谨(lai)的思路. 首先都知道对于 ...

  7. HDU 1069 dp最长递增子序列

    B - Monkey and Banana Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I6 ...

  8. HDU 1160 DP最长子序列

    G - FatMouse's Speed Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64 ...

  9. hdu 4826(dp + 记忆化搜索)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4826 思路:dp[x][y][d]表示从方向到达点(x,y)所能得到的最大值,然后就是记忆化了. #i ...

随机推荐

  1. 【搜索】POJ-3009 DFS+回溯

    一.题目 Description On Planet MM-21, after their Olympic games this year, curling is getting popular. B ...

  2. 简单复利计算c语言实现

    #include<stdio.h>#include<math.h>float i; //利率 float p; //期初金额 float F; //未来值 int n; //期 ...

  3. poj 1144(割点)

    题目链接:http://poj.org/problem?id=1144 题意:给出一个无向图,求关键节点的个数. 分析:双连通分量Tarjan算法直接求割点就行了,裸的模板题. AC代码: #incl ...

  4. ACM数论之旅8---组合数(组合大法好(,,• ₃ •,,) )

    组合数并不陌生(´・ω・`) 我们都学过组合数 会求组合数吗 一般我们用杨辉三角性质 杨辉三角上的每一个数字都等于它的左上方和右上方的和(除了边界) 第n行,第m个就是,就是C(n, m) (从0开始 ...

  5. Java并发编程之线程生命周期、守护线程、优先级、关闭和join、sleep、yield、interrupt

    Java并发编程中,其中一个难点是对线程生命周期的理解,和多种线程控制方法.线程沟通方法的灵活运用.这些方法和概念之间彼此联系紧密,共同构成了Java并发编程基石之一. Java线程的生命周期 Jav ...

  6. 利用ZooKeeper简单实现分布式锁

    1.分布式锁的由来: 在程序开发过程中不得不考虑的就是并发问题.在java中对于同一个jvm而言,jdk已经提供了lock和同步等.但是在分布式情况下,往往存在多个进程对一些资源产生竞争关系,而这些进 ...

  7. 深入理解JAVA虚拟机阅读笔记3——垃圾回收器

    一.垃圾收集器总览 新生代:Serial. ParNew. Parallel Scavenge 老年代:CMS.Serial Old. Parallel Old 最新的:G1 并行和并发的区别: 并行 ...

  8. ASP.NET MVC中在 @RenderBody() 或者 @Html.Partial()中需要使用引入外部js,css

    今天想在后台封装一下bootstraptree这个插件,引入jquery.js bootstrap.js bootstrap.css bootstrap-tree.js后,我在页面查看脚本错误就连最简 ...

  9. iOS 简单获取当前地理坐标

    iOS 获取当前地理坐标        iOS获取当前地理坐标,很简单几句代码,但是如果刚开始不懂,做起来也会也会出现一些问题. 1.导入定位需要用到的库:CoreLocation.framwork ...

  10. python selenium wait方法

    遇到一个网站运行很慢,所以要等待某个元素显示出来之后再进行操作,自己手上的书上没有例子可以直接用 发现一篇文章:http://www.cnblogs.com/yoyoketang/p/6517477. ...