贪心 - Clam and Fish - 2020牛客暑期多校训练营(第三场)

贪心 - Clam and Fish - 2020牛客暑期多校训练营(第三场)

题意:

T n 0 1 2 3 T组测试用例,每组包括一个长度为n的字符串,由'0'、'1'、'2'、'3'组成。

0 0:当前阶段没有鱼、没有鱼饵。

1 1:当前阶段没有鱼、有鱼饵。

2 2:当前阶段有鱼、没有鱼饵。

3 3:当前阶段有鱼、有鱼饵。

每个阶段,只允许进行四种操作:

①、若有鱼饵,可以拿一份鱼饵。

②、若有一条鱼,可以直接捕一条鱼,无需花费。

0 ③、在任何阶段,只要携带的鱼饵数量大于0,就可以花费一个鱼饵来捕捉一条鱼。

④、什么都不做。

计算最多能够捕捉多少条鱼。

输入:

T ( 1 t 2.5 × 1 0 5 ) 首行:T(1≤t≤2.5×10 ^5),测试样例的数量。

n ( 1 n 2 × 1 0 6 ) 接下来每组数据,包括n(1≤n≤2×10^6),字符串的长度。

n n 再输入一行长度为n的字符串,表示n个阶段。

T组样例,n的总和不超过2×106

输出:

一个整数,表示捕捉到的鱼的数量的最大值。

示例1

输入

2
4
0103
1
1

输出

2
0

分析:

先逐个分析每个阶段:

0 0 阶段0:什么也没有,此时若携带的鱼饵数量大于0,必然是选择捕一条鱼。

2 0 阶段2:有鱼没鱼饵,那直接0代价捕鱼。

3 使 使 1 阶段3:有鱼有鱼饵,此时选择捕鱼是最优的。因为即使增加鱼饵,也至多使得鱼的数量增加1。

1 阶段1:没鱼有鱼饵,未必要选择增加鱼饵。因为鱼饵最后可能会剩余,所以也可以选择捕鱼。

0 2 3 1 因此我们发现,阶段0、2、3的操作都是确定的,只有阶段1需要考虑是选择增加鱼饵还是捕鱼。

1 什么样的情况下选择在阶段1捕鱼呢?

i 1 i 0 假设设当前所处的位置i处在阶段1,若i以后存在的阶段0的数量要少于当前拥有的鱼饵数量,就无需再增加鱼饵了。

因为再增加鱼饵,最后必然会有鱼饵剩余。所以我们在这种情况下选择捕鱼。

i 0 捕完一条鱼后,鱼饵数量将与i以后的阶段0的数量相等。按照这样的贪心策略,就能够得到最优解。

i 0 c n t 0 [ i ] 由于我们要快速查询第i位以后的所有阶段中,阶段0的数量。故我们要先预处理数组cnt0[i]。

时间复杂度: O ( n ) O(n)

注意:

T n 2 × 1 0 6 T组测试样例n的总和不超过2×10^6,

c n t 0 0 n 对于每组测试数据,cnt0数组无需全部初始化为0,仅需初始化前n位即可。

用memset会超时!

T 这里T了好几发。

代码:

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
  
using namespace std;
  
const int N=2e6+10;
  
int T,n;
char str[N];
int cnt0[N];
  
int main()
{
    cin>>T;
    while(T--)
    {
        //memset(cnt0,0,sizeof cnt0);
       	for(int i=0;i<=n+2;i++) cnt0[i]=0;
       	
        int res=0,ecnt=0;
        scanf("%d",&n);
        scanf("%s",str);
        for(int i=n-2;i>=0;i--)    //第i以后有多少个0
        {
            cnt0[i]=cnt0[i+1];
            if(str[i+1]=='0') cnt0[i]++;
        }
          
        for(int i=0;i<n;i++)
        {
            if(str[i]=='0' && ecnt) {res++;ecnt--;}
            else if(str[i]=='2'||str[i]=='3') res++;
            else if(str[i]=='1')
            {
                if(ecnt>cnt0[i]) {res++;ecnt--;}
                else ecnt++;
            }
        }
        printf("%d\n",res);
    }
  
    return 0;
}

猜你喜欢

转载自blog.csdn.net/njuptACMcxk/article/details/107453059