HDU - 5037 Frog 贪心+初值 2014 ACM/ICPC Asia Regional Beijing Online

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiang_6/article/details/81914367

题意:

在一片河塘中,有只青蛙从0点开始,要跳到m点,这条线上起初有n个荷叶,每次青蛙最大能跳k米

现在让你添加一些荷叶,让他能跳到m点,问最大的跳跃次数,注意,青蛙每次采取最优策略(尽量少跳)

思路:

青蛙采取最优策略的话就是每次选能跳到的最远点跳,队友存在的荷叶,我们没办法做手脚

只有在青蛙没法往前跳,需要我们添加荷叶的时候,我们贪心的选择一些位置,让他多跳一些

假如青蛙跳到的上一个位置是pre(坐标),并且无法跳到下一个位置a[i],(即:a[i]-pre > k);因为我们要让他多跳,所以我们选尽量小的位置让他跳,但是这个位置必须是他上上个跳到的位置last到达不了的,那就是last+k+1这个位置;

我们令t=pre-last, d=(k+1)-t;  那么pre到a[i] 之间的位置差值是 d-t-d-t-d-t··· 这样的循环,我们只要看他们之间有多少个这样的循环节,还有一个问题就是最后的a[i] 有可能由前面的就可以跳到了,那样就相当于少了一个t的一段,特判一下

需要注意的是,开始时候的last怎么赋值,我因为这个查了好久的bug,,,如果青蛙从初始位置没办法往后跳的话,那我们放的第一个荷叶一定是在第一个位置的,因为前面不会影响,所以last我们要设初值为(-k);

扫描二维码关注公众号,回复: 2972084 查看本文章
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

const int maxn = 2e5 + 7;
int a[maxn];

int main() {
  int T; scanf("%d", &T);
  int kase = 1;
  int n, m, k;
  while(T--) {
    scanf("%d%d%d", &n, &m, &k);
    for(int i = 1; i <= n; ++i) {
      scanf("%d", &a[i]);
    }
    sort(a+1,a+1+n); a[n+1] = m; a[n+2] = 2e9+77;
    int last = -k, pre = 0, ans = 0;
    for(int i = 1; i <= n+1; ++i) {
      if(a[i] - pre > k) {
        int L = a[i] - pre;
        int t = pre-last, d = k+1-t;
        int t1 = L%(k+1);
        ans += (L/(k+1) * 2);

        if(t1+t <= k) {
          ans--;
          pre = a[i]-t1-t;
          last = pre-d;
        }
        else {
          pre = a[i]-t1;
          last = pre-t;
        }
        i--;
      }
      else if(a[i]-pre <= k && a[i+1]-pre > k) {
        last = pre;
        pre = a[i];
        ans++;
      }
    }
    printf("Case #%d: %d\n", kase++, ans);
  }
  return 0;
}

猜你喜欢

转载自blog.csdn.net/xiang_6/article/details/81914367