gmoj 6839. 【2020.11.5提高组模拟】淘淘蓝蓝喜欢 01串

6839. 【2020.11.5提高组模拟】淘淘蓝蓝喜欢 01串

题目大意

一个01串,每次操作有两步:

1.删除其中一个字符

2.若字符串不为空,删除同种元素组成的最长前缀

求最大操作数

Solution

蔑说这题连结论题都算不上……

考虑贪心

因为每次操作肯定会把至少一个块删掉,所以我们贪心的想让它对后面的块影响减小

假设当前第一个块只有一个元素,如果删掉第一个元素则后面一个块也会同时被删掉,这种情况显然不是最优的

所以我们考虑每个块最多删剩一个元素

最后删完后序列中可能还存有一些零零散散的大小为1的块

这时暴力删就行了

code

#include <cstdio>
#include <algorithm>
#define N 100001
#define open(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout);
using namespace std;
int t,n,now,cnt,i,ans,pl,num[N];
bool bz[N];
char s[N];
int main()
{
    open("str");
    scanf("%d",&t);
    for (;t;t--)
    {
        scanf("%d",&n);
        now=-1;cnt=0;
        scanf("%s",s+1); 
        for (i=1;i<=n;i++)
        {
            if (s[i]!=now)
            {
                num[++cnt]=1;
                now=s[i];
            }else num[cnt]++;
        }
        for (i=1;i<=cnt;i++)
            bz[i]=0;
        pl=1;
        for (i=1;i<=cnt;i++)
        {
            while (bz[pl] || num[pl]==1) pl++;
            if (pl>cnt) break;
            num[pl]--;
            ans++;
            bz[i]=1;
        }
        pl=0;
        for (i=1;i<=cnt;i++)
            if (!bz[i]) pl++;
        ans+=pl/2+(pl%2==1);
        printf("%d\n",ans);
        ans=0;
    }
    return 0;
}

posted @ 2020-11-05 20:45  Sport_River  阅读(289)  评论(0编辑  收藏  举报