Codeforces Round #450 (Div. 2) E. Maximum Questions dp,重载小于号

E. Maximum Questions
time limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Vasya wrote down two strings s of length n and t of length m consisting of small English letters ‘a’ and ‘b’. What is more, he knows that string t has a form “abab…”, namely there are letters ‘a’ on odd positions and letters ‘b’ on even positions.

Suddenly in the morning, Vasya found that somebody spoiled his string. Some letters of the string s were replaced by character ‘?’.

Let’s call a sequence of positions i, i + 1, …, i + m - 1 as occurrence of string t in s, if 1 ≤ i ≤ n - m + 1 and t1 = si, t2 = si + 1, …, tm = si + m - 1.

The boy defines the beauty of the string s as maximum number of disjoint occurrences of string t in s. Vasya can replace some letters ‘?’ with ‘a’ or ‘b’ (letters on different positions can be replaced with different letter). Vasya wants to make some replacements in such a way that beauty of string s is maximum possible. From all such options, he wants to choose one with the minimum number of replacements. Find the number of replacements he should make.

Input
The first line contains a single integer n (1 ≤ n ≤ 105) — the length of s.

The second line contains the string s of length n. It contains small English letters ‘a’, ‘b’ and characters ‘?’ only.

The third line contains a single integer m (1 ≤ m ≤ 105) — the length of t. The string t contains letters ‘a’ on odd positions and ‘b’ on even positions.

Output
Print the only integer — the minimum number of replacements Vasya has to perform to make the beauty of string s the maximum possible.

Examples
input
5
bb?a?
1
output
2
input
9
ab??ab???
3
output
2
题意:s串种有一些?,可以用a,b填充,问最小填多少个?,可以得到最多的不相交的t串。
做法:dp[i]代表从i到n之间最多可以构造多少个t,最小花费是多少,题意给出不相交,那么从n到1处理,对于当前的i,它取dp[i+1]到dp[n]的最大值(可以通过重载小于号实现),和以它为起点构造,让从i+m到n取最大值,然后加上从i开始的贡献和费用就好了。重载小于号是一个好东西、

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+100;
char s[N],t[N];
int num[N];
int mx[N];
int n,m;
struct node{
    int x,c;
    void init(){
        x=c=0;
    }
    node add(int a,int b){
        node now;
        now.x = x+a;
        now.c = c+b;
        return now;
    }
    void print(){
        cout << "print" << x << ' '<< c << endl;
    }
    bool operator<(const node &p)const{
        if(x == p.x) return c > p.c;
        return x < p.x;
    }
};
node sum[N<<2];

void update(int x,node &tmp,int l,int r,int rt){
    if(l == r){
        sum[rt] = tmp;
        return ;
    }
    int mid = l+r>>1;
    if(mid >= x) update(x,tmp,l,mid,rt<<1);
    else update(x,tmp,mid+1,r,rt<<1|1);
    sum[rt] = max(sum[rt<<1],sum[rt<<1|1]);
}
node query(int L,int R,int l,int r,int rt){
    if(L <= l && R >= r){
        return sum[rt];
    }
    int mid = l+r>>1;
    node tmp;
    tmp.init();
    if(mid >= L) tmp = query(L,R,l,mid,rt<<1);
    if(mid < R) tmp = max(tmp,query(L,R,mid+1,r,rt<<1|1));
    return tmp;
}
int main(){
    scanf("%d",&n);
    scanf("%s",s+1);
    scanf("%d",&m);
    for(int i = 1;i <= n;i ++) {
        if(s[i] == '?') num[i] = 1;
        if(i) num[i] += num[i-1];
    }
    for(int i = n;i >= 1;i --){
        if(s[i] == '?'||s[i] == 'a'){
            if(i < n&&(s[i+1] == '?'||s[i+1] == 'b')){
                mx[i] = mx[i+2]+2;
            }
            else mx[i] = 1;
        }
        else mx[i] = 0;
        node now = query(i,n,1,n,1);

        if(mx[i] >= m){
            node ret;
            ret.init();
            if(i+m <= n) ret = query(i+m,n,1,n,1);
            ret = ret.add(1,num[i+m-1]-num[i-1]);
            now = max(now,ret);
        }
        //cout <<"now : " << now.x << ' '<< now.c << endl;
        //query(1,n,1,n,1).print();
        update(i,now,1,n,1);
    }
    node ans = query(1,n,1,n,1);
    cout <<  ans.c << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/zstu_zy/article/details/78780464