标签:end type lin cin else class 链接 include std
题目链接:https://codeforces.com/contest/1091/problem/F
首先考虑一个贪心的策略,我们在岩浆上飞,在水里游,在路上走,这样一路走到结尾。但我们发现途中会出现几种情况。
情况1:
我们遇到了岩浆,但是剩余的能量不够我们飞行过去,这时候我们要在前面通过原地转圈蓄能量。我们可以全局维护当前走过的路中是否有水,如果有,我们就以\(3\)代价原地走路,否则,只能以\(5\)代价原地走路。
情况2:
走到结尾的时候,我们有剩余的能量,这时候我们要通过把走路和游泳换成飞行以提高速度。那么先考虑把移动的慢的走路换成飞行,注意每还一格要扣两点能量,注意到并不是所有的陆地都能用来换成飞行,就比如岩浆前的陆地要用来蓄能量等,所以我们每走一次地形将当前的陆地的两倍与能量取\(min\)。注意到最后可能把陆地全换成飞行之后依然有剩余的能量,这时候我们就把在水中游泳换成飞行即可,方法同陆地。
时间复杂度\(O(n)\),空间复杂度\(O(n)\)。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#include <iostream>
#include <algorithm>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <iomanip>
#include <assert.h>
#include <fstream>
using namespace std;
typedef long long ll;
const int MAXN = 100005;
int n;
ll l[MAXN];
string s;
int main()
{
ios::sync_with_stdio(false);
cin >> n;
for (int i = 0;i < n;i++)
cin >> l[i];
cin >> s;
bool haveW = 0;
ll sumG = 0,energy = 0,ans = 0;
for (int i = 0;i < n;i++)
{
if (s[i] == ‘L‘)
{
if (energy < l[i])
{
ans += (haveW ? 3 : 5) * (l[i] - energy);
energy = l[i];
}
ans += l[i];
energy -= l[i];
}
if (s[i] == ‘W‘)
{
ans += 3 * l[i];
energy += l[i];
haveW = true;
}
if (s[i] == ‘G‘)
{
ans += 5 * l[i];
sumG += 2 * l[i];
energy += l[i];
}
sumG = min(sumG,energy);
}
if (energy > 0)
{
if (energy <= sumG)
ans -= energy * 2;
else
{
ans -= sumG * 2;
energy -= sumG;
ans -= energy;
}
}
cout << ans << endl;
return 0;
}
标签:end type lin cin else class 链接 include std
原文地址:https://www.cnblogs.com/Hazyknight/p/10233839.html