Decomposition into Good Strings (想法dp)

原题:Gym-100971M

题意:

给一个k,一个字符串,问你可以找到最少多少个子串组成这个字符串,且每个子串包含恰好k个不同字母

第i个输出对应的字符串为前i长度原字符串

解析:

刚开始的时候被最少唬住了,后来才知道和最少也没多大关系

遍历到i个字母的时候,取最后面一个不同字符为k的一个串,就可以从前面的dp加一转化过来

当然,还有一种情况就是有多个不同字符为k的子串,…abc和..aabc

那么假设前面可以(不为-1),在后面符合要求(==k)的情况下把第一个a加到前面可能就会变多,不是最少了
如果前面不行,我们为了不输出-1,可能把第一个a加过去

代码:


D read(){ D ans=0; char last=' ',ch=getchar();
while(ch<'0' || ch>'9')last=ch,ch=getchar();
while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
if(last=='-')ans=-ans; return ans;
}

int num[30];
int dp[200009];

int main(){
    int k=read();
    string x;cin>>x;int n=x.length();x=' '+x;
    int sum=0;int l=1;
    for(int i=1;i<=n;i++){
        num[x[i]-'a']++;if(num[x[i]-'a']==1)sum++;
        if(sum<k){ dp[i]=-1;continue;}
        while(l<i&&sum>k){l++,num[x[l-1]-'a']--;if(num[x[l-1]-'a']==0)sum--;}
        while(dp[l-1]==-1&&num[x[l]-'a']>1){
            num[x[l]-'a']--;l++;
        }
        if(dp[l-1]==-1)dp[i]=-1;
        else dp[i]=dp[l-1]+1;
    }
    for(int i=1;i<=n;i++){
        printf("%d%c",dp[i],i==n?'\n':' ');
    }
}

猜你喜欢

转载自blog.csdn.net/jk_chen_acmer/article/details/81325077