P1431 守望者的逃离

描述

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

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

格式

输入格式

在输入文件escape.in仅一行,包括空格隔开的三个非负整数M,S,T。

输出格式

在输出文件escape.out包括两行:
第1行为字符串“Yes”或“No”(区分大小写),即守望者是否能逃离荒岛。
第2行包含一个整数。
第一行为“Yes”(区分大小写)时表示守望者逃离荒岛的最短时间;
第一行为“No”(区分大小写)时表示守望者能走的最远距离。

样例1

样例输入1

39 200 4

样例输出1

No
197

样例2

样例输入2

36 255 10

样例输出2

Yes
6

限制

1s

提示

30%的数据满足:1<=T<=10,1<=S<=100
50%的数据满足:1<=T<=1000,1<=S<=10000
100%的数据满足:1<=T<=300000,0<=M<=1000,1<=S<=10^8

来源

NOIP2007普及组第3题

题解

DP

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define LL long long
#define INF 0x3f3f3f3f
using namespace std;

LL M,S,T;

struct f{
    LL magic, dis, ans;
} dp[300010];

int main()
{
    cin >> M >> S >> T;
    dp[0].magic = M;
    dp[0].dis = dp[0].ans = 0;

    for(int i = 1;i <= T;i++){
        dp[i].ans = dp[i].dis = dp[i].magic = 0;

        if(dp[i-1].magic >= 10){
            dp[i].magic = dp[i-1].magic-10;
            dp[i].dis = dp[i-1].dis+60;
        } else {
            dp[i].magic = dp[i-1].magic+4;
            dp[i].dis = dp[i-1].dis;
        }
        dp[i].ans = max(dp[i-1].ans+17,dp[i].dis);
        if(dp[i].ans >= S){
            cout << "Yes" << endl;
            cout << i <return 0;
        }
    }

    cout << "No" << endl;
    cout << dp[T].ans << endl;

    return 0;
}

题意:
小岛逃生,距离是 S ,跑的速度是 17m/s ,闪现技能是 60m/次
但是每次闪现都会消耗 10点魔法值。若是原地不动,魔法值会每秒
增加 4点
现在知道距离是 S ,魔法值的总点数是 M ,可以逃生的时间是 T
需要计算:
1.若是能逃出生天,最少需要的时间是多少
2.若是不能逃出,在时间 T 内可以逃跑的最长距离是多少

分析
1.对问题进行抽象:
用掉 10点魔法值 — 消耗 1s时间 —> 可以向前移动60m
用掉 -4点魔法值 — 消耗 1s时间 —> 可以向前移动 0m
用掉 0 点魔法值 — 消耗 1s时间 —> 可以向前移动17m
2.找到子问题:
【在第 i 秒的时候,可以移动的最长距离】
第 i 秒的移动距离,取决于上一秒的移动距离
3.找到状态转移方程
dp[i] = max{ dp[i-1]+60(魔法值-10), dp[i-1]+17, dpi-1 }
其中 dp[i-1]+60(魔法值-10) 的条件是 {魔法值>=10}

简单迭代
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define LL long long
#define MAX_N 110
#define INF 0x3f3f3f3f
using namespace std;

int M,S ,T;

int main()
{
    cin >> M >> S >> T;
    int x = 0,y = 0;

    for(int i = 1;i <= T;i++){
        if( M >= 10 ){
            x+=60;
            M-=10;
        } else {
            x = x;
            M+=4;
        }
        y+=17;
        if(x >= y){
            y = x;
        }
        if(y >= S){
            cout << "Yes"<< endl;
            cout << i << endl;
            return 0;
        }
    }
    cout << "No" << endl;
    cout << y << endl;
    return 0;
}

你可能感兴趣的:(动态规划)