给出点集,和不大于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. 生命周期事件和 Global.asax 文件

    文章:IIS 5.0 和 6.0 的 ASP.NET 应用程序生命周期概述 该文章有介绍Application_Start方法

  2. 结对项目:四则运算web

    1)Coding.Net项目地址 https://git.coding.net/DandelionClaw/WEB_Calculator.git 注:本项目为web端,并且需要连接SQL Server ...

  3. JS计算两个日期之间的天数,时间差计算

    1.日期之间的天数计算 //计算天数差的函数,通用 function DateDiff(sDate1, sDate2) { //sDate1和sDate2是2017-9-25格式 var aDate, ...

  4. 模拟alert,confirm 阻塞状态

    /*** * 模拟alert弹窗 * content 为弹框显示的内容 * 确定按钮对应的下面取消关闭显示框 * **/function oAlert(content) { var oWrap = $ ...

  5. 配置docker的私有仓库

    1:安装docker-registry包 yum install -y docker-distribution   2:启动docker-distribution,默认监听于TCP/5000端口 sy ...

  6. 四人小组:vip会员管理系统

    需求概述: 针对各类商铺百花齐放的现状,越来越多的商家考虑用各种方式招揽顾客,会员制度一向是吸引回头客的不二法宝.用户持有会员卡能够迅捷的购物,享有普通顾客更多的优惠或回馈.乃至新品推送.积分等一系列 ...

  7. poj 1966(顶点连通度)

    题意:给出一个n个节点和m条边的图,求该图的顶点连通度. 分析: 顶点连通度的求解可以转换为网络最大流问题. (1)原图G中的每个顶点v变成网络中的两个顶点v‘和v’‘,顶点v’至v''有一个条弧(有 ...

  8. C 语言assert使用

    1.assert宏的原型定义在<assert.h>中,其作用是如果它的条件返回错误,则终止程序执行,原型定义:#include <assert.h>void assert( i ...

  9. ACdream原创群赛__15

    这场感觉题目确实还算可以,不过,说好的每题10s效果上却不理想.这个时限还算比较紧.因为时间不是按绝对的多出几秒来计算,而是几倍来计算的. 比赛做的不好,后面又去做了一下. A:典型的数位DP,一直坑 ...

  10. Nginx在Linux上的安装和配置

    链接:http://www.cnblogs.com/wbyp/p/7737224.html