给出点集,和不大于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. 关于mybatis的思考(3)——ResultMaps的使用

    ResultMap元素在mybatis中非常重要,目的是告诉mybatis将从结果集中取出的数据转换为开发者需要的对象.     UserMapping.xml <!-- selectAll操作 ...

  2. 深入理解JAVA I/O系列二:字节流详解

    流的概念 JAVA程序通过流来完成输入/输出.流是生产或消费信息的抽象,流通过JAVA的输入输出与物理设备链接,尽管与它们链接的物理设备不尽相同,所有流的行为具有相同的方式.这样就意味一个输入流能够抽 ...

  3. centos7开机出现try again to boot into default maintenance give root password for maintenance

    开启centos7出现下面两句话,然后直接输出root密码,就可以登录,但是登录后,发现一些文字显示出来的是乱码 try again to boot into default maintenanceg ...

  4. 我所理解的Delphi中的数组类型

    数组可以使Object Pascal所拥有的任何数据类型,数组是一些数值的简单集合. var   MyArray: ..] of Integer;        { 声明一个数组包括5个整数数值} b ...

  5. 计算机网络【8】—— Get和Post请求的区别

    get参数通过url传递,post放在request body中. get请求在url中传递的参数是有长度限制的,而post没有. get比post更不安全,因为参数直接暴露在url中,所以不能用来传 ...

  6. html实现鼠标悬停变成手型实现方式

    1.采用a标签实现的方式 <a href="javascript:void()">内容</a> 2.采用CSS实现的方式 // 变手形 oElement.s ...

  7. double 和 im2double 的区别

    double 就是简单地把一个变量类型转换成double型,数值大小不变. 函数im2double将输入换成double类型.如果输入是unit8,unit16或者是二值的logical类型,则函数i ...

  8. python自动化之读写

    ############################################################################# #############在Windows上 ...

  9. MySQL复制 -- 复制出错怎么办?

    假如我们生产环境复制出错?该怎么办呢? 下面提供几种办法: 1. 手工处理,补回不一致数据(可以利用主库来补数据.也可以利用binlog来补数据) 2.用开源工具来解决一致性问题 3.自己造轮子,解决 ...

  10. 【刷题】BZOJ 3930 [CQOI2015]选数

    Description 我们知道,从区间[L,H](L和H为整数)中选取N个整数,总共有(H-L+1)^N种方案.小z很好奇这样选出的数的最大公约数的规律,他决定对每种方案选出的N个整数都求一次最大公 ...