HDU5037-贪心(很好)-Frog

重点就是造成这种情况, 以保证次数最大。
当长度为l+1次,让其跳两次。
那么余数的情况呢??
存一个变量,记录的为上一个区间最后的点和原来已经存在的石子的位置(不会大于l+1,如果大了就会再跳一次)。而这时青蛙,宁愿跳的更远,所以不会跳 以前的石子,但是又不得不跳以前的石子。
所以这时可以+1.
当青蛙跳上以后,为了让他跳的更多,我们先给他l+1让他跳。然后在让他跳多于的位置。这样又会使他在一个短位置跳一次,
(正常情况我们应该将这俩位置连起来算一次,这样青蛙会很开心)
(初始化的结果是青蛙不能够攒步数)
这里写图片描述
由第一个图我们可以发现,如果想要青蛙的步数最大,那么后面那个石头尽可能的近并且正好不能够横跨过他。
可以发现当 长度为l+1时,可以让青蛙跳两次,这是最好的情况。
然后我们只需要对区间内找到l+1的个数就好了。
注意mod l+1的那部分,我们也是希望他最后一步跳这么远,而不是越过。可以看见下面那一个图
这里写图片描述

我们可以让 他的第一个石头距离原始石头为b,并且当a+b==l+1时,青蛙就要走一步 ,长度为a,到达原始石子处,然后继续进行l+1的行驶,我们就会发现此时的b就是 下一个石子长度mod l+1的长度。当他走过时,对下一个的影响也是b。
而当a+b小于等于l时,对下一个的影响将是累加的。
(为什么图中最后不能b在前a在后,因为如果b>a,那么就会使青蛙走的更远,如果a>b,那么两个b在一起可能会让青蛙跳过其中一个。)




#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;
/*尽可能的让青蛙多跳,。那就是如果那个青蛙
就是在他刚好跳过的第一个地方放石头,给他过

*/
const int maxn=200006;
int st[maxn];
int main()
{   int t;
    int m,n,l;
    scanf("%d",&t);
    for(int tt=1;tt<=t;tt++){
       scanf("%d%d%d",&m,&n,&l);
        for(int i=1;i<=m;i++)
            scanf("%d",&st[i]);
        st[0]=0;st[++m]=n;
        sort(st,st+m+1);
        int k=l;
        int ans=0;
          for(int i=0;i<=m;i++)
          {
            int x=(st[i]-st[i-1])%(l+1);
            int y=(st[i]-st[i-1])/(1+l);
            if(k+x>l)
            {
                ans+=2*y+1;
                k=x;
            }
            else
            {
                ans+=2*y;
                k+=x;
            }
        }
        printf("Case #%d: %d\n",tt,ans);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值