Hdu 5037 Frog(2014 ACM/ICPC Asia Regional Beijing Online)[贪心 || 想法]

来源:互联网 发布:wdcp如何选择php版本 编辑:程序博客网 时间:2024/05/21 09:55

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5037

题目的意思比较简单,

说,一个青蛙需要过河,河宽抽象成一维坐标轴,为m。初始,青蛙在0点,每次他最多能条L个单位长度,即从0 ->L,初始时候有n个石头在河内,并且青蛙可以踩在石头上。但是,河内的石头不一定能够使得青蛙跳到对岸。现在上帝可以帮助青蛙,即放入河内一些石头使青蛙能够过河,但是,上帝想要青蛙跳最多的次数。问青蛙最多条几次才能够过河。 N, M, L (0<=N<=2*10^5,1<=M<=10^9, 1<=L<=10^9)。


比赛期间没有想明白为什么。。

看题解后明白了,贪心。。

我们应该明白的知道一些结论:

1.青蛙每次都会以最优的策略来的,所以不可否认的是,如果它每次都条到最远的话,肯定步数会更少。

2.如果最初始的时候,石头就能过跳过,上帝加石头是无用的。。为什么?

因为,如果你加到能够跳到最远的石头的左边,它会忽略,加到右边,它可以选择的策略会更优,这不是上帝想要看到。所以....

所以,我们的贪心策略就出来了。

1.尽可能的把不能跳过的距离分成多的L+1份,这样青蛙需要跳过的步数就会更多。

2.需要注意的是,青蛙的下一步是和它前面的一步长度是有关系的。。

如下图:

Code:

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <cmath>using namespace std;const int N = 2 *  1e5 + 4;int n, m, L, po[N];int solve(){    int pre = L, ans = 0;    for(int i = 1; i <= n; i ++){        int x = (po[i] - po[i - 1]) / (L + 1);        int y = (po[i] - po[i - 1]) % (L + 1);        if(y + pre >= L + 1){ //            pre = y;            ans += (x * 2 + 1);        }        else {            pre = y + pre;            ans += x * 2;        }    }    return ans;}int main(){//    freopen("1.txt", "r", stdin);    int T, k = 1;    scanf("%d", &T);    while(T --){        scanf("%d %d %d", &n, &m, &L);        for(int i = 1; i <= n; i ++){            scanf("%d", &po[i]);        }        po[0] = 0; po[++ n] = m;        sort(po, po + n);        printf("Case #%d: %d\n", k ++, solve());    }    return 0;}



0 0