前言:感觉自己读题不仔细,A题本来就是一个简单贪心,就因为读题时漏了这个,以为上一stage的fish和clam能保留至这个阶段。这个惨痛的经历告诉我没搞清楚题意前坚决不开写。
题意:游戏有n个stage,每个stage有4种状态,各个stage之间互不影响,上一个stage的fish和clam不能保留至这一阶段,唯一能保留的就是鱼饵fish bait。同时在每个stage你可以有题目给出的四种操作,问如何操作使得最后得到的鱼数量最多。
题解:通过题意易得,每次操作最多得到一条鱼,那么当stage为2或者3时,我们果断取鱼即可。问题在于当stage为1并且我们有鱼饵时,我们到底该将stage中的clam变为鱼饵还是用鱼饵钓鱼?这取决于后面stage为0的个数,如果后面stage为0的个数还很多,那么很显然将clam变为鱼饵更划算。那么我们可以从后往前遍历,如果1后面还有0那么将1标记,然后将1和0的个数各减一。最后satge为1被标记的都可以将clam变为鱼饵。
代码
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<bitset>
#include<cassert>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<deque>
#include<iomanip>
#include<list>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
using namespace std;
typedef long long ll;
typedef long double ld;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
const double PI=acos(-1.0);
const double eps=1e-6;
const ll mod=1e9+7;
const int inf=0x3f3f3f3f;
const int maxn=2e6+10;
const int maxm=100+10;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int book[maxn];
char s[maxn];
int main()
{
ios;
int t;
scanf("%d",&t);
while(t--)
{
int n;
scanf("%d%s",&n,s);
int tmp0=0,tmp1=0;
for(int i=n-1;i>=0;i--)
{
book[i]=0;
if(s[i]=='0')
{
tmp0++;
tmp1=0;
}
if(s[i]=='1')
{
tmp1++;
if(tmp0>=tmp1)
{
book[i]=1;
tmp0--;
tmp1--;
}
}
}
int ans=0,fish=0,ge=0,er=0;
for(int i=0;i<n;i++)
{
if(s[i]=='2') ans++;
else if(s[i]=='3') ans++;
else if(s[i]=='1')
{
if(book[i]) er++;
else
{
if(er>0) ans++,er--;
else er++;
}
}
else
{
if(er>0) ans++,er--;
}
}
printf("%d\n",ans);
}
}