hdu 5037 Frog 【贪心】




点击打开链接


题意:

           一个青蛙过河,他它跳跃范围是k (k范围内能跳到任何地方),它不能游泳,只能通过河上面的木桩,可以看作是线性的,抵达m起点是0,

          你首先一定要让它能过和,然后让他条约次数最大。

题解:

         很明显,在他的跳跃范围内,他一定会选择一个最远的点来跳跃。如果这个范围内有石头,你就不应该添加石头,你在改石头之前添加是无用功,

         之后添加是对青蛙有利       的,所以,只有在他的跳跃范围之内没有石头的情况时,你才需要添加石头,当然添加石头要尽可能的向左,

         但是要保证前一个石头不能一下子跳过来,只能是该点向后跳。


直接模拟一步一步跳超时,,亲测。

然后写了一个二分每次选择能跳的最远的,,,跑到1000ms wa。。。

后来发现,根本不用二分石头,直接一个石头一个石头跳就可以了。


#include<iostream>
#include<cstdio>
#include<cstring>
#include<set>
#include<algorithm>
#define ll long long
using namespace std;
const int maxn=2e5+5;
int n,m,k;
int stone[maxn];
int main(){
    int T;
    scanf("%d",&T);
    for(int ca=1;ca<=T;++ca){
        scanf("%d %d %d",&n,&m,&k);
        for(int i=1;i<=n;++i)
            scanf("%d",&stone[i]);
        stone[n+1]=m;
        sort(stone+1,stone+1+n);
        int pos=0,step=0,pre=-k;    
        for(int i=1;i<=n+1;++i){
            step+=(stone[i]-pos)/(k+1)*2;
            pre+=(stone[i]-pos)/(k+1)*(k+1);
            if(stone[i]-pre>k){
                pre=pos+(stone[i]-pos)/(k+1)*(k+1);
                step++;
            }
            pos=stone[i];
        }
        printf("Case #%d: %d\n",ca,step);
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值