HDU5037-贪心(很好)-Frog

来源:互联网 发布:淘宝开店名字可以改吗 编辑:程序博客网 时间:2024/04/25 21:15

重点就是造成这种情况, 以保证次数最大。
当长度为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;}
原创粉丝点击