gym 100820G Racing Gems(二维LIS,好题)

35 篇文章 1 订阅
34 篇文章 0 订阅
本文介绍了一种赛车游戏策略问题,玩家需在限定区域内收集最多宝石。通过对宝石位置的分析,转化为二维最长不下降子序列(LIS)问题,通过排序和动态规划求解最大收集数量。
摘要由CSDN通过智能技术生成

题目链接

Racing Gems

You are playing a racing game. Your character starts at the x axis (y = 0) and proceeds up therace track, which has a boundary at the line x = 0 and another at x = w. You may start the raceat any horizontal position you want, as long as it is within the track boundary. The finish line isat y = h, and the game ends when you reach that line. You proceed at a fixed vertical velocity v,but you can control your horizontal velocity to be any value between v/r and v/r, and change itat any time.

There are n gems at specific points on the race track. Your job is to collect as many gems aspossible. How many gems can you collect?

Input

The first line of input contains four space-separated integers n, r, w, and h (1 n 105, 1 r 10,1 w,h 109). Each of the following n lines contains two space-separated integers xi and yi,denoting the coordinate of the ith gem (0 xi w, 0 < yi h). There will be at most one gemper location.

The input does not include a value for v.Output

Print, on a single line, the maximum number of gems that can be collected during the race.

page15image12768

Sample Input

5 1 10 1088
51
46

4779

Sample Output

3



题意:

你在进行一场赛车,初始时你在(x, 0)位置,x属于[0, w]。当到达y=h时,比赛结束。

有n个宝石,第i个宝石的坐标是(xi, yi)。不会有多个宝石在一个位置的情况。

若赛车的y方向的速度为v,那么x方向的速度在[-v/r, v/r]区间,速度可随意调整。

现在不给出v,问最多能够收集到多少宝石。


(1 <= n <= 1e5, 1 <= r <= 10, 1 <= w, h <= 1e9)。

(0 <= xi <= w, 0 <= yi <= h)。

n, r, w, h, xi, yi都为整形变量。


参考博客链接

题解:

把题目转换一下就能发现,当赛车在某个位置时,它接下来能拾到的金币的位置是跑道的位置和两条射线夹的面积的相交部分。假如我们让这两条射线分别与赛道两旁的边界相交,那么就能得到两个数字,分别记为a,b

最后我们能发现,本身是一个DAG模型,但是由于都很庞大,但是转换成(a,b) 以后,如果想捡了这个金币后还能捡到下一个金币,那么就要保证下一个金币的A比a大且B比b大,也可以相等。那么这就变成了一个二维无序LIS了,有一种很简单的方法就是,把a从小到大排序,那么之后对b做最长不下降子序列,那么就是答案了。因为此时能保证a绝对不会下降。


#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#include<stack>
using namespace std;
#define rep(i,a,n) for (int i=a;i<n;i++)
#define per(i,a,n) for (int i=n-1;i>=a;i--)
#define pb push_back
#define fi first
#define se second
typedef vector<int> VI;
typedef long long ll;
typedef pair<int,int> PII;
const ll inf=1e18;
const ll mod=1000000007;
const int maxn=1e5+100;
struct node
{
    ll a,b;
    bool operator <(const node& s)const{
        return a<s.a;
    }
    node(ll x=0,ll y=0):a(x),b(y) {}
}a[maxn];
ll d[maxn];
int main()
{
    int n,r,w,h;
    while(~scanf("%d%d%d%d",&n,&r,&w,&h))
    {
        rep(i,1,n+1)
        {
            ll x,y;
            scanf("%lld%lld",&x,&y);
            a[i].a=1ll*x*r+y;
            a[i].b=1ll*(w-x)*r+y;
        }
        sort(a+1,a+n+1);
        fill(d,d+n,inf);
        rep(i,0,n)
        {
            *upper_bound(d,d+n,a[i+1].b)=a[i+1].b;
        }
        printf("%d\n",lower_bound(d,d+n,inf)-d);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值