【贪心】Buaacoding1682 绝望的超时空步兵

绝望的超时空步兵
时间限制: 1000 ms 内存限制: 65536 kb
总通过人数: 29 总提交人数: 37
题目描述
超时空步兵的身上有一个可以用来短程传送的装置,但传送的距离是固定的,而且每次传送都要耗费使用者一定的体力值。

现在超时空步兵和大部队走散了,而且他不小心走到了辐射工兵们设下的辐射场里。留给他走出辐射场的时间已经不多了。已知:

超时空步兵每秒能奔跑17米。(请不要在意他这比博尔特还快的速度)

超时空步兵使用传送装置,可以在一秒向前突进60米。但是要消耗10点体力值。

超时空步兵在原地不动,每秒钟可以恢复4点体力值。

超时空步兵每秒钟能恢复1点体力值。(即使选择休息或者传送,也并不影响这1点体力的恢复)

现在已知超时空步兵的初始体力值M,他所在的初始位置和安全位置之间的距离S,他走出辐射场的安全时间T,请计算如何在最短的时间内跑到安全位置。如果不能跑到,则输出在时间T内超时空步兵能移动的最远距离。

为了简化问题,超时空步兵的奔跑、传送和休息均以秒为单位,且每次活动持续的时间为整数秒。(不能做出诸如休息0.5秒这样的行为)

输入
多组输入数据

每组数据一行,为用空格隔开的三个非负整数M,S,T

1 <= T <= 10000, 0 <= M<=100, 1 <=S <= 10^6

输出
对于每组数据,输出:

第1行为字符串“Yes”或“No” ,即超时空步兵是否能逃离辐射场。

第2行包含一个整数,

第一行为“Yes” 时表示超时空步兵跑到安全位置的最短时间

第一行为“No” 时表示超时空步兵能跑的最远距离。

输入样例
9 77 2
9 94 3
8 94 3
8 60 2
37 1000 28
输出样例
Yes
2
Yes
3
Yes
3
Yes
2
No
754


 软院算法上机的一道题,神奇的是当场没人写出来。真心不水啊。一开始是当成一个贪心+dp写的,也就是先不采用奔跑17米的方式,而是采用传送和等待的方式。一直到时间逼近结束或者路程逼近终点的时候开始使用dp。自己觉得写得挺对的,代码很长,狂WA不止。(后来写完正解之后,才意识到可能dp的范围还是太小了)
 第二天仔细分析了一下。认为应该是贪心。可以发现

  1. 走17放在之前一定比放在之后要好,这是因为放在之前可以得到的1个体力,之后更有可能给传送使用。所以最好的方式是先走x个17步,再用传送和等待。
  2. 走17要略微坏于传送,这个有一点直觉。实际上,以1000个17为例,用时1000,产生1000体力,而同样用时1000,可以先等待两次,传送一次,重复284次,这样前进了17040,再休息1000-2843=148,于是得到了284+148(4+1)=1024体力,体力和路程都是后者更优。因此我们可以枚举上限到999。
  3. 虽然求解时间和求解路程对应的策略可能是不一样的,但是这两种答案都包含在了这1000条路线中了。

 以后像这样的贪心题,还是要多练习。另外,本题上限好像可以比999要小,具体就不会证了。听说这好像是cf的原题qwq,以后要多练习cf了~

#include<cstdio>
#include<algorithm>
using namespace std;

int m,s,t,p,q;

bool get_ans(int m, int s, int t, int i)
{
	int f=0,dis=0;
	while(f<t&&dis<s)
	{
		if(m<10)
			m+=5;
		else
		{
			m-=9;
			dis+=60;
		}
		f++;
	}
	if(dis>=s)
		p=min(f+i,p);
	else
		q=max(dis+i*17,q);
	return dis>=s;
}

int main()
{
	while(scanf("%d%d%d",&m,&s,&t)==3)
	{
		p=1E9,q=0;
		bool f=false;
		for(int i=0;i<1000&&t>=i&&s-17*i>=0;i++)
			f|=get_ans(m+i,s-17*i,t-i,i);
		if(f)
			printf("Yes\n%d\n",p);
		else
			printf("No\n%d\n",q);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值