1. 程式人生 > >洛谷 P1095 守望者的逃離 dp 貪心

洛谷 P1095 守望者的逃離 dp 貪心

href 鏈接 lse turn www. false 之間 使用 span

題目鏈接

https://www.luogu.org/problemnew/show/P1095

題目描述

惡魔獵手尤迪安野心勃勃,他背叛了暗夜精靈,率領深藏在海底的娜迦族企圖叛變。守望者在與尤迪安的交鋒中遭遇了圍殺,被困在一個荒蕪的大島上。為了殺死守望者,尤迪安開始對這個荒島施咒,這座島很快就會沈下去。到那時,島上的所有人都會遇難。守望者的跑步速度為17m/s,以這樣的速度是無法逃離荒島的。慶幸的是守望者擁有閃爍法術,可在1s內移動60m,不過每次使用閃爍法術都會消耗魔法值10點。守望者的魔法值恢復的速度為4點/s,只有處在原地休息狀態時才能恢復。

現在已知守望者的魔法初值M,他所在的初始位置與島的出口之間的距離S,島沈沒的時間T。你的任務是寫一個程序幫助守望者計算如何在最短的時間內逃離荒島,若不能逃出,則輸出守望者在剩下的時間內能走的最遠距離。註意:守望者跑步、閃爍或休息活動均以秒(s)為單位,且每次活動的持續時間為整數秒。距離的單位為米(m)。

輸入格式:

共一行,包括空格隔開的三個非負整數M,S,T。

輸出格式:

共兩行。

第1行為字符串“Yes”或“No”(區分大小寫),即守望者是否能逃離荒島。

第2行包含一個整數。第一行為“Yes”(區分大小寫)時表示守望者逃離荒島的最短時間;第一行為“No”(區分大小寫)時表示守望者能走的最遠距離。

題解

我們發現最優解的行動次序並不影響答案,所以我們假設先全用魔法,再跑步。先用\(f[i]\)\(i\)秒只用法術的最遠距離,然後再枚舉時間,在哪個後面跑步能使答案更優,並更新答案。

代碼

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=3e5+10;
int m,s,t;
int f[maxn];
int main(){
    ios::sync_with_stdio(false);
    cin>>m>>s>>t;
    for(int i=1;i<=t;i++){
        if(m>=10){m-=10;f[i]=f[i-1]+60;}
        else{f[i]=f[i-1];m+=4;}
    }    
    for(int i=1;i<=t;i++){
        if(f[i]<f[i-1]+17)f[i]=f[i-1]+17;
        if(f[i]>=s){cout<<"Yes"<<endl<<i<<endl;return 0;}
    }
    cout<<"No"<<endl<<f[t]<<endl;
    return 0;
}

洛谷 P1095 守望者的逃離 dp 貪心