1. 程式人生 > 實用技巧 >gmoj 6839. 【2020.11.5提高組模擬】淘淘藍藍喜歡 01串

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;
}