GYM 100820 G.Racing Gems(LIS)
2017-07-19 08:58
351 查看
Description
在[0,w]x[0,h]的区域内赛车,初始时可以任意选取x轴上[0,w]内一点作为起点,只要到达y=h在[0,w]范围内任一点即为到达终点,赛车的垂直车速为v,水平车速可以在-v/r~v/r内任意变化,给出该区域内n个钻石的坐标,问在赛车过程中最多可以拿到多少钻石
Input
第一行输入四个整数n,r,w,h,之后n行每行两个整数表示一颗钻石的坐标(1<=n<=1e5,1<=r<=10,1<=w,h<=1e9,0<=x[i]<=w,0<=y[i]<=h)
Output
输出最多可以拿到的钻石数量
Sample Input
5 1 10 10
8 8
5 1
4 6
4 7
7 9
Sample Output
3
Solution
当赛车拿到一个钻石后,其下一个可以拿到的钻石所处范围必须要在以第i个点往上的斜率分别为-r和r的射线之间,设由第i个点发出的两条射线与左右边界交点的纵坐标分别为a[i]和b[i],那么拿到钻石i后可以拿到钻石j等价于钻石j在由第i个点发出的这两条射线之间,进一步等价于a[j]>=a[i],b[j]>=b[i],所以求出每个钻石发出射线与左右两边界的交点(a[i],b[i]),问题变成求这个二维序列的最长上升子序列长度,先按第一维升序排,对第二维求一个最长上升子序列即可
Code
在[0,w]x[0,h]的区域内赛车,初始时可以任意选取x轴上[0,w]内一点作为起点,只要到达y=h在[0,w]范围内任一点即为到达终点,赛车的垂直车速为v,水平车速可以在-v/r~v/r内任意变化,给出该区域内n个钻石的坐标,问在赛车过程中最多可以拿到多少钻石
Input
第一行输入四个整数n,r,w,h,之后n行每行两个整数表示一颗钻石的坐标(1<=n<=1e5,1<=r<=10,1<=w,h<=1e9,0<=x[i]<=w,0<=y[i]<=h)
Output
输出最多可以拿到的钻石数量
Sample Input
5 1 10 10
8 8
5 1
4 6
4 7
7 9
Sample Output
3
Solution
当赛车拿到一个钻石后,其下一个可以拿到的钻石所处范围必须要在以第i个点往上的斜率分别为-r和r的射线之间,设由第i个点发出的两条射线与左右边界交点的纵坐标分别为a[i]和b[i],那么拿到钻石i后可以拿到钻石j等价于钻石j在由第i个点发出的这两条射线之间,进一步等价于a[j]>=a[i],b[j]>=b[i],所以求出每个钻石发出射线与左右两边界的交点(a[i],b[i]),问题变成求这个二维序列的最长上升子序列长度,先按第一维升序排,对第二维求一个最长上升子序列即可
Code
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> #include<cmath> #include<vector> #include<queue> #include<map> #include<set> #include<ctime> using namespace std; typedef long long ll; #define INF 1e12 #define maxn 111111 int n,r,w,h; struct node { ll a,b; bool operator<(const node&c)const { if(a!=c.a)return a<c.a; return b<c.b; } }p[maxn]; ll a[maxn],dp[maxn]; int LIS(ll a[])//求序列a的(非严格)最长上升子序列 { for(int i=1;i<n;i++)dp[i]=INF; dp[0]=a[0]; int len=1; for(int i=1;i<n;i++) { if(a[i]>=dp[len-1])dp[len++]=a[i]; else dp[upper_bound(dp,dp+n,a[i])-dp]=a[i]; } return len; } int main() { while(~scanf("%d%d%d%d",&n,&r,&w,&h)) { for(int i=0;i<n;i++) { ll x,y; scanf("%I64d%I64d",&x,&y); p[i].a=1ll*r*x+y,p[i].b=1ll*r*(w-x)+y; } sort(p,p+n); for(int i=0;i<n;i++)a[i]=p[i].b; printf("%d\n",LIS(a)); } return 0; }
相关文章推荐
- Gym-100820 Racing Gems(二维LIS)
- 【2015-2016 ACM-ICPC Pacific Northwest Regional Contest (Div 1)G】【坐标轴变换 LIS】Racing Gems 开车吃宝石,横向速度不能超
- 【坐标变换】【二维偏序】【线段树】Gym - 100820G - Racing Gems
- Gym 101246H ``North-East''(LIS)
- Gym 101246.H - “North-East” (二维LIS变形)
- gym 100820G Racing Gems(二维LIS,好题)
- UVaLive 7374 Racing Gems (DP,LIS)
- 【LIS】【递推】Gym - 101246H - ``North-East''
- Gym - 101246H ``North-East''【思维+nlogn LIS】
- 最长单调子序列LIS的简单动态规划算法
- Gym-100781A 【树的直径 + 思维】
- [LIS] 动态规划及其简单优化
- Gym 101164.I - Cubes(爆搜剪枝)
- 关于最长递增子序列问题的求解(LIS)
- 【推导】【贪心】【高精度】Gym - 101194E - Bet
- RQNOJ 合唱队形(LIS最大上升序列解析)
- [Treap] [LIS] BZOJ[3173] [Tjoi2013]最长上升子序列
- Android入门第一篇layout,onclicklisenter
- Gym 101482.H - Hyacinth (构造)
- 最长递增子序列(LIS) 学习中ing