Codeforces 1091F - New Year and the Mallard Expedition (贪心、模拟)

Good Bye 2018 F. New Year and the Mallard Expedition


题意

一只鸭子想从数轴的左端走到右端

数轴上有三种环境:草原Grass,水Water,岩浆Lava

给定一个长度为\(n\)的字符串,表示自左向右的环境分布

再给定一个长度为\(n\)的数组,表示每种环境占的宽度

在草原上,鸭子只能走或者飞

在水上,鸭子只能游或者飞

在岩浆上,鸭子只能飞

鸭子走的速度为一米\(5\)秒,游的速度为一米\(3\)秒,飞的速度为一米\(1\)

同时,鸭子每走一米或者游一米可以积攒\(1\)个单位的体力,飞一米需要消耗\(1\)个单位的体力

鸭子不需要严格移动整数距离,比如宽度为\(5\)的草原可以走\(2.5\)米飞\(2.5\)

鸭子也可以往回走或者游,用于积攒体力

初始时鸭子体力为\(0\),问从左端走到右端的最短时间,保证题目有解(即第一种环境一定不是岩浆)


限制

\(1\leq n\leq 10^5\)

\(1\leq l_i\leq 10^{12}\)




思路

贪心模拟

假设目前我们需要经过一段长度为\(len\)的区域

方法有:

  • 草原限定:走\(\frac {len} 2\)米,飞\(\frac {len} 2\)米,时间消耗\(5*\frac {len} 2+1*\frac {len} 2=3*len\)
  • 水域限定:走\(\frac {len} 2\)米,飞\(\frac {len} 2\)米,时间消耗\(3*\frac {len} 2+1*\frac {len} 2=2*len\)
  • 如果在这之前有水域是飞行经过的,那么可以将某一段从飞行改成游泳,每米将会多使用\(3-1=2\)秒的时间,但能量会从\(-1\)变成\(+1\),所以时间消耗\(\frac{(3-1)*len}{2}+1*len=2*len\)
  • 如果在这之前有草原是飞行经过的,那么可以将某一段从飞行改成走路,每米将会多使用\(5-1=4\)秒的时间,但能量会从\(-1\)变成\(+1\),所以时间消耗\(\frac{(5-1)*len}{2}+1*len=3*len\)
  • 如果之前有经过水域,那么可以让鸭子往回游积攒体力,时间消耗为\(3*len+1*len=4*len\)
  • 如果之前有经过草原,那么可以让鸭子往回走积攒体力,时间消耗为\(5*len+1*len=6*len\)

所以对于本题,需要使用\(isWater\)\(isGrass\)记录某个位置之前是否存在水域或者草原

使用\(flyWater\)\(flyGrass\)记录某个位置之前在水域上飞行了多少米,在草原上飞行了多少米(也就是有多少米能用来更改)

所以可以进行模拟——

  • 如果当前是草原,那么检查是否前面的水域中存在飞行经过的区域(因为将飞行改成游泳\(2*len\)比直接走并飞行\(3*len\)所花的时间少),再直接走并飞行
  • 如果当前是水域,那么直接走并飞行(\(2*len\)已经是最短时间了)
  • 如果当前是岩浆,根据花费的时间排序(\(2\lt3\lt4\lt6\)),先判断并将某一段从飞行改成游泳,再判断并将某一段从飞行改成走路,再尝试让鸭子往回游积攒体力,最后尝试让鸭子往回走积攒体力



程序

(343ms/1000ms)

//#include<ext/pb_ds/assoc_container.hpp>
//#include<ext/pb_ds/hash_policy.hpp>
#include<bits/stdc++.h>
#define closeSync ios::sync_with_stdio(0);cin.tie(0);cout.tie(0)
#define multiCase int T;cin>>T;for(int t=1;t<=T;t++)
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define repp(i,a,b) for(int i=(a);i<(b);i++)
#define per(i,a,b) for(int i=(a);i>=(b);i--)
#define perr(i,a,b) for(int i=(a);i>(b);i--)
#define pb push_back
#define eb emplace_back
#define mst(a,b) memset(a,b,sizeof(a))
using namespace std;
//using namespace __gnu_pbds;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> P;
const int INF=0x3f3f3f3f;
const ll LINF=0x3f3f3f3f3f3f3f3f;
const double eps=1e-12;
const double PI=acos(-1.0);
const double angcst=PI/180.0;
const ll mod=998244353;
ll gcd(ll a,ll b){return b==0?a:gcd(b,a%b);}
ll qmul(ll a,ll b){ll r=0;while(b){if(b&1)r=(r+a)%mod;b>>=1;a=(a+a)%mod;}return r;}
ll qpow(ll a,ll n){ll r=1;while(n){if(n&1)r=(r*a)%mod;n>>=1;a=(a*a)%mod;}return r;}
ll qpow(ll a,ll n,ll p){ll r=1;while(n){if(n&1)r=(r*a)%p;n>>=1;a=(a*a)%p;}return r;}

int n;
double len[100050];
char str[100050];

void solve()
{
    cin>>n;
    rep(i,1,n)
        cin>>len[i];
    cin>>str+1;
    
    bool isWater=false,isGrass=false;
    double ans=0;
    double flyWater=0,flyGrass=0;
    double tmp;
    rep(i,1,n)
    {
        if(str[i]=='G')
        {
            if(flyWater)
            {
                tmp=min(len[i],flyWater*2);
                flyWater-=tmp/2;
                len[i]-=tmp;
                flyGrass+=tmp;
                ans+=tmp/2*(3-1)+tmp*1;
            }
            ans+=len[i]*3;
            flyGrass+=len[i]/2;
            isGrass=true;
        }
        else if(str[i]=='W')
        {
            ans+=len[i]*2;
            flyWater+=len[i]/2;
            isWater=true;
        }
        else
        {
            if(flyWater)
            {
                tmp=min(len[i],flyWater*2);
                flyWater-=tmp/2;
                len[i]-=tmp;
                ans+=tmp/2*(3-1)+tmp*1;
            }
            if(flyGrass)
            {
                tmp=min(len[i],flyGrass*2);
                flyGrass-=tmp/2;
                len[i]-=tmp;
                ans+=tmp/2*(5-1)+tmp*1;
            }
            if(isWater)
            {
                ans+=len[i]*(3+1);
                len[i]=0;
            }
            if(isGrass)
            {
                ans+=len[i]*(5+1);
                len[i]=0;
            }
        }
        //cerr<<i<<' '<<ans<<'\n';
    }
    cout<<(ll)ans<<'\n';
}
int main()
{
    closeSync;
    //multiCase
    {
        solve();
    }
    return 0;
}

posted @ 2020-10-26 23:02  StelaYuri  阅读(161)  评论(0编辑  收藏  举报