给你一行房间,有的是隐身药水,有的是守卫,有的是金币。
你可以任选起点,向右走,每经过一个药水或金币就拿走,每经过一个守卫必须消耗1个药水,问你最多得几个金币。
药水看成左括号,守卫看成右括号,
就从每个位置贪心地向右走,如果在 r 遇到不匹配,则把下一次的左端点置成r+1,接着走。
O(n)即可。
因为如果把左端点放在上次的l和r之间,要么会发生不匹配,要么答案无法比上次走的更优。
队友代码:
#include <iostream> #include <cstdio> #include <cmath> #include <algorithm> #include <map> #include <cstring> #include <vector> #include <ctime> using namespace std; char s[1100000]; int now,all,i,l,ans; int main() { // freopen("ac.in","r",stdin); // freopen("ac.out","w",stdout); gets(s); l=strlen(s); for (i=0;i<l;i++) { if (s[i]=='K') { all--; if (all<0) { now=0; all=0; continue; } } if (s[i]=='M') { now++; ans=max(ans,now); } if (s[i]=='H') all++; } printf("%d ",ans); }