• codeforces上某题


    一道codeforces上的题目。

    题目大意:

    定义有k个不同的字符的字符串为好字符串。现在给出一个字符串,求解对该字符串的每个前缀Si至少是多少个好字符串的连接,若不能由好字符串连接而成则输出-1。
    例:k = 2
    abac至少是ab和ac这两个好字符串的连接。
    字符串长度<=2e5

    看了一下网上的题解都是这样子的
    DP+数据结构
    尺取+dp+线段树
    比较麻烦。

    列出基本DP式:f[i]={f[j]+1} S(j+1)-i为好串
    显然对于i,满足条件的j的区间是单调不降的,因此,可以放一个指针j在i后面,若j-i的串超过限制或f[j]==-1,j直接向前跳,因为满足条件的j区间单调不降,所以前面的f[]是没用的。由于f[]单调不降,所以跳到k>=num就停,然后更新答案,这样一定最优。

    代码:

    #include<iostream>
    #include<cstring>
    #include<string>
    #include<cstdio>
    #include<iomanip>
    #include<algorithm>
    #include<cmath>
    #include<vector>
    #include<set>
    #include<map>
    #include<cstdlib>
    using namespace std;
    #define ll long long
    #define up(i,j,k) for(int i=(j);i<=(k);i++)
    #define cmin(a,b) a=min(a,b)
    #define cmax(a,b) a=max(a,b)
    #define pii pair<int,int>
    const int maxn=400010,inf=1e9,mod=1e9+7;
    int read(){
        int ch=getchar(),x=0,f=1;
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
        return f*x;
    }
    
    int f[maxn];
    char s[maxn];
    int k,n;
    int vis[26],num=0;
    void add(int x){
        vis[x]++;
        if(vis[x]==1)num++;
    }
    void erase(int x){
        vis[x]--;
        if(!vis[x])num--;
    }
    int main(){
        k=read();scanf("%s",s+1);n=strlen(s+1);
        int sum=-1,head=0;
        for(int i=1;i<=n;i++){
            add(s[i]-'a');
            while((num>k||f[head]==-1)&&head<i)erase(s[++head]-'a');
            if(f[head]==-1||num!=k)f[i]=-1;
            else f[i]=f[head]+1;
        }
        up(i,1,n)printf("%d%c",f[i],i==n?'
    ':' ');
        return 0;
    }
    View Code
  • 相关阅读:
    c#冒泡排序
    C# 虚方法(virtual)覆盖(override) 隐藏(new) 重载
    Javascript 大括号
    C# const.static.readonly.
    热点链接(img map area)
    WeiBo返回错误码的二种方式
    Cookie跨域操作
    synchronized(this)与synchronized(class)
    线程安全场景备忘
    git新建一个分支setupstream
  • 原文地址:https://www.cnblogs.com/chadinblog/p/9201290.html
Copyright © 2020-2023  润新知