您的位置:首页 > 其它

hdu 5037 Frog(贪心)

2015-08-27 20:58 344 查看
题意:有一只青蛙想从0点跳到M点、从0点到M点有N块石头,给出你N块石头的位置、青蛙跳跃的长度为0~L、你上帝,当青蛙无法跳跃的时候你可以帮助它、

可以无限制的在池塘内任何一点添加石头,并且你是仁慈的,一定会让这个青蛙到达对岸 也就是M点、 你想让青蛙尽可能的跳跃多次,到达对岸、青蛙是聪明的,

它跳跃的时候会选取它跳跃的最优解来跳跃、 问这只青蛙一最多跳跃多少次可以到达M点、

自己做的时候也是很朦胧,想的头大、 看了别人的解题报告,最后终于搞懂了该怎么做、

思路:一道贪心题、 首先定义三个整形变量k,x,y、 三个变量k代表的是青蛙的位置到现在我要找的位置之前的位置的距离 (比如说,有三块石头,分别在坐标轴上的3 7 15 三个点,青蛙跳跃的最大距离L=14 , 此时青蛙的位置在三的位置上、 当找到7的位置时,k=3-7=4 此时的距离小于14 所以我不一定要跳跃,我需要往后面找,当我找到15这个点的时候 k=4+(15-7) 因为从3到7的距离我已经计算过了,此时我需要找的位置为7到15这个点,此时k=12 由于L=14 所以我也不一定要跳跃,k的值表示的就是
青蛙的位置与要找的位置之间的距离) x变量表示的是两个石头之间的相对距离, 相对距离指的是两个石头之间的距离有可能大于青蛙跳跃的距离L,所以一定要青蛙跳跃两次,因为两个石头之间的距离如果大于L青蛙便跳不过去,这样便有机会使它跳跃的次数变得更多、所以x应该等于两个石头之间的距离%L+1取余, 如果两个石头之间的距离为L那么便符合青蛙跳跃最大的条件了,但是呢,我想要使青蛙跳跃的次数最多,所以我不想让它跳过去,不想让它跳过去的最短距离便为L+1、 这样便可以使青蛙跳跃的次数最大、 y代表的是两个石头中间的距离中有几个L+1
、 如果有一个L+1那么我跳跃的次数一定是两次、 这个是一定的 、 其实x和y都是很好理解的,最主要的是k 与x之间的关系,

k与x之间的关系,k与x之间有两种情况,一种是k+x<=L 那么我有可能跳跃,因为x的值是相对的x,所以其中有可能有L+1段是超过的,这个看代码应该就可以读懂、如果k+x<+L 就说明我不需要跳跃,因为此时不一定是最优解、 而另一种情况k+x> L 此时我需要跳跃,跳跃的次数为多少呢? 一定为y*2+1次 因为我x中间有可能有超过L+1的部分所以要y*2 那么此时我的相对x值与k值相加是>L的所以需要多加一个1 那么此时我的k值为多少呢? k应该等于x 因为我想要k值应该取最大,k值越大那么我越有可能大于L
那么青蛙跳跃的次数就越多、 最后输出青蛙跳跃的次数就可以了、

k的值要赋值为L ,因为默认第一次一定是能跳跃的,跳跃的次数为y*2+1、 这个自己想一想就可以理解的、

AC代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=200005;
int N,M,L,T;
int w[maxn];
int ans,x,y,k,cnt;

int main()
{
scanf("%d",&T);
cnt=0;
while(T--){
scanf("%d %d %d",&N,&M,&L);
for(int i=1;i<=N;i++)
scanf("%d",&w[i]);
w[++N]=M; ans=0;w[0]=0;
sort(w,w+N);
k=L;
for(int i=1;i<=N;i++){
x=(w[i]-w[i-1])%(L+1);
y=(w[i]-w[i-1])/(L+1);
if(x+k<=L){
k+=x;
ans+=y*2;
}
else{
k=x;
ans+=y*2+1;
}
}
printf("Case #%d: %d\n",++cnt,ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: