Vijos P1431 守望者的逃离 (动态规划+贪心)(未解决)

来源:互联网 发布:kik是什么软件 编辑:程序博客网 时间:2024/03/29 09:36

描述

恶魔猎手尤迪安野心勃勃,他背叛了暗夜精灵,率领深藏在海底的娜迦族企图叛变。守望者
在与尤迪安的交锋中遭遇了围杀,被困在一个荒芜的大岛上。为了杀死守望者,尤迪安开始对这
个荒岛施咒,这座岛很快就会沉下去。到那时,岛上的所有人都会遇难。守望者的跑步速度为
17m/s,以这样的速度是无法逃离荒岛的。庆幸的是守望者拥有闪烁法术,可在1s内移动60m,不
过每次使用闪烁法术都会消耗魔法值10点。守望者的魔法值恢复的速度为4点/s,只有处在原地
休息状态时才能恢复。
现在已知守望者的魔法初值M,他所在的初始位置与岛的出口之间的距离S,岛沉没的时间T。

你的任务写写一个程序帮助守望者计算如何在最短的时间内逃离荒岛,若不能逃出,则输出守望
者在剩下的时间能走的最远距离。注意:守望者跑步、闪烁或休息活动均以秒(s)为单位,且每
次活动的持续时间为整数秒。距离的单位为米(m)。

分析

还是先从分析入手来解决这个问题,那么很明显,我们的决策就是我们在每秒钟的时候是要选择跑步呢,还是使用魔法呢,还是恢复魔法呢,之后就要清楚的是我们作出决策的策略是什么,这也是粉明显,我们的策略就是在“跑的更远”或“用时更少”,这两个策略是否相同呢,就是说如果能够逃脱的话,那么用时必定小余海岛沉没的时间t,比如说逃出去用时t1,那么这个时候必然是在t1时候的最大移动距离x,那么也就是说我们这两种情况其实是可以用一个状态和一种决策策略来解决的。那么为了解决这个问题,我们来定义一个状态,由刚才的分析可知我们的距离x必定是状态本身,可以用时间做为参数,所以我们定义f[i]是“在is内移动的最大距离”,那么我们的策略必定是使得f[i]最大,那么和明显如果在i时刻能够使用魔法的话,那么我们必定会使用魔法,如何选择另外的两个选型就是关键的问题,这个时候我们就不能怕麻烦而要仔细的分情况考察了。
首先,我们来分析最普通的情况,即我们在蓄力和使用时都不会面临边界,那么如果我们现在的法力值为0,那么我们从蓄力到使用完需要4s时间,移动距离为60米,而如果期间我们选择跑步的话,我们会跑出68米的距离,那么很明显,如果我们的法力值为0的话,我们压根就不会选择蓄力!那么同理当我们的法力值为1时也是如此,当我们有2点法力的时候,我们从蓄力到使用需要3s,移动距离为60m,而期间如果选择跑步的话,会移动51m,所以当法力值大于等于2小于10的时候我们选择蓄力,但还要考虑到如果在蓄力期间达到边界条件时候的判断,即如果在蓄力的时间内还没来的及使用魔法,时间就用完了的话那么明显就不划算了,还有一种情况是比如说如果我们的距离用不着60m就出去了,那么我们也不划算了。
好,最后让我们来仔细分析这些特殊情况,第一种,蓄力时间内还没来的及使用魔法,时间就用完了,这种情况我们可以在每次决策之间加一个判断,判断剩下的时间是否能够使用完魔法,第二种,在选择之前加一个判断,判断条件是剩下的距离跑步用时是否比用蓄力并用魔法少。经过我们的数据分析分出了几种情况代码如下
////  main.cpp//  守望者////  Created by 张嘉韬 on 16/1/20.//  Copyright © 2016年 张嘉韬. All rights reserved.////#include <iostream>#include <cstring>using namespace std;int main(){    freopen("/Users/zhangjiatao/Desktop/input.txt","r",stdin);    int m,s,t,f[500000],flag;    flag=0;    memset(f,0,sizeof(f));    cin>>m>>s>>t;    for(int i=1;i<=t;i++)    {        if(m>=10) f[i]=f[i-1]+60,m=m-10;        else if(m>=6&&m<=9)        {            if(t-i<=1) f[i]=f[i-1]+17;            else if(s-f[i-1]<=17) f[i]=f[i-1]+17;            else f[i]=f[i-1],m+=4;        }        else if(m>=2&&m<=5)        {            if(t-i<=2) f[i]=f[i-1]+17;            else if(s-f[i-1]<=34) f[i]=f[i-1]+17;            else f[i]=f[i-1],m+=4;        }        else f[i]=f[i-1]+17;        if(f[i]>=s)        {            cout<<"Yes"<<endl;            cout<<i<<endl;            //cout<<f[i]<<endl;            flag=1;            break;        }    }    if(flag==0)    {        cout<<"No"<<endl;        cout<<f[t]<<endl;    }    return 0;}

0 0
原创粉丝点击