CodeForces - 163B Lemmings (排序+二分)

B. Lemmings
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

As you know, lemmings like jumping. For the next spectacular group jump n lemmings gathered near a high rock with k comfortable ledges on it. The first ledge is situated at the height of h meters, the second one is at the height of 2h meters, and so on (the i-th ledge is at the height of i·h meters). The lemmings are going to jump at sunset, and there's not much time left.

Each lemming is characterized by its climbing speed of vi meters per minute and its weight mi. This means that the i-th lemming can climb to the j-th ledge in  minutes.

To make the jump beautiful, heavier lemmings should jump from higher ledges: if a lemming of weight mi jumps from ledge i, and a lemming of weight mj jumps from ledge j (for i < j), then the inequation mi ≤ mj should be fulfilled.

Since there are n lemmings and only k ledges (k ≤ n), the k lemmings that will take part in the jump need to be chosen. The chosen lemmings should be distributed on the ledges from 1 to k, one lemming per ledge. The lemmings are to be arranged in the order of non-decreasing weight with the increasing height of the ledge. In addition, each lemming should have enough time to get to his ledge, that is, the time of his climb should not exceed t minutes. The lemmings climb to their ledges all at the same time and they do not interfere with each other.

Find the way to arrange the lemmings' jump so that time t is minimized.

Input

The first line contains space-separated integers nk and h (1 ≤ k ≤ n ≤ 1051 ≤ h ≤ 104) — the total number of lemmings, the number of ledges and the distance between adjacent ledges.

The second line contains n space-separated integers m1, m2, ..., mn (1 ≤ mi ≤ 109), where mi is the weight of i-th lemming.

The third line contains n space-separated integers v1, v2, ..., vn (1 ≤ vi ≤ 109), where vi is the speed of i-th lemming.

Output

Print k different numbers from 1 to n — the numbers of the lemmings who go to ledges at heights h, 2h, ..., kh, correspondingly, if the jump is organized in an optimal way. If there are multiple ways to select the lemmings, pick any of them.

Examples
input
Copy
5 3 2
1 2 3 2 1
1 2 1 2 10
output
5 2 4
input
Copy
5 3 10
3 4 3 2 1
5 4 3 2 1
output
4 3 1
Note

Let's consider the first sample case. The fifth lemming (speed 10) gets to the ledge at height 2 in  minutes; the second lemming (speed 2) gets to the ledge at height 4 in 2 minutes; the fourth lemming (speed 2) gets to the ledge at height 6 in 3 minutes. All lemmings manage to occupy their positions in 3 minutes.


题意:n只袋鼠跳k个ledges(听说叫壁架,可以理解为一个距离),每只袋鼠有一个重量m,以及跳跃速度v,对于i个ledges,距离为i * h,当i < j 时,必须满足mi<=mj ,现在让你安排k只袋鼠到k个终点,使得全部袋鼠都到位的时间最短。

数据范围:(1 ≤ k ≤ n ≤ 10^5, 1 ≤ h ≤ 10^4) (1 ≤ mi ≤ 10^9) (1 ≤ vi ≤ 10^9) 

思路:对于袋鼠根据重量从小到大排序,重量相同按速度从小到大排序,然后二分最短时间(精度要求较高,亲测至少要二分100次以上才能通过)

关于二分检测:对于某一个时间,每一只袋鼠所能到达的最高ledges为 t * v / h⌋,预处理出所有袋鼠所能达到的最高ledges,然后从后往前扫,贪心一下(能选就选,即如果当前需要选择的是第k ledges的袋鼠,那所有>=k皆可选),若能成功选取k个,则说明当前选择的时间太大。。。。。


代码如下:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <map>
#include <cmath>
#include <cstring>
#include <utility>
#include <list>
#include <vector>
#include <cstdlib>
#define rep(i,n) for(ll i=1;i<=n;i++)
#define repn(i,n) for(ll i=n;i>=1;i--)
#define mst(a,x) memset(a,x,sizeof(a))
#define ll long long
using namespace std;
const ll maxn = 100000;
const ll maxm = 1000000;
const double pi = 3.141592653589793;
const double e = 2.718281828459045;
struct node
{
    ll m,v,xh;
    bool operator <(const node &r)const
    {
        if(m!=r.m) return m < r.m;
        else return v < r.v;
    }
}d[maxn + 50];
ll b[maxn + 50];
ll res[maxn + 50];
int main()
{
#ifdef local
    freopen("in.txt","r",stdin);
#endif // local
    ll n,k,h; scanf("%lld%lld%lld",&n,&k,&h);
    for(ll i=1;i<=n;i++) scanf("%lld",&d[i].m);
    for(ll i=1;i<=n;i++) scanf("%lld",&d[i].v),d[i].xh = i;
    sort(d+1,d+n+1);
//    for(ll i=1;i<=n;i++) cout << d[i].m << " ";
//    cout << endl;
//    for(ll i=1;i<=n;i++) cout << d[i].v << " ";
//    cout << endl;
    double L = 0,R = 1e9;
    for(int j=1;j<=100;j++) //二分次数
    {
        double mid = (L+R)/2.0;
        for(ll i=1;i<=n;i++) b[i] = (ll)(mid * d[i].v / h);
        ll tmp = k;
        for(ll i=n;i>=1;i--)
            if(b[i]>=tmp) tmp--;
        if(tmp<=0) R = mid;
        else L = mid;
    }
    for(ll i=1;i<=n;i++) b[i] = (ll)(R * d[i].v / h);
    ll tmp = k;
    for(ll i=n;i>=1;i--)
    {
        if(b[i]>=tmp) res[tmp--] = d[i].xh;
        if(tmp==0) break;
    }
    for(ll i=1;i<=k;i++) printf("%lld ",res[i]);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值