前言:感觉自己读题不仔细,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) ;
}
}