zoukankan      html  css  js  c++  java
  • 洛谷 P1136 迎接仪式 题解

    题目描述

    LHX教主要来X市指导OI学习工作了。为了迎接教主,在一条道路旁,一群Orz教主er穿着文化衫站在道路两旁迎接教主,每件文化衫上都印着大字。一旁的Orzer依次摆出“欢迎欢迎欢迎欢迎……”的大字,但是领队突然发现,另一旁穿着“教”和“主”字文化衫的Orzer却不太和谐。

    为了简单描述这个不和谐的队列,我们用“j”替代“教”,“z”替代“主”。而一个“j”与“z”组成的序列则可以描述当前的队列。为了让教主看得尽量舒服,你必须调整队列,使得“jz”子串尽量多。每次调整你可以交换任意位置上的两个人,也就是序列中任意位置上的两个字母。而因为教主马上就来了,时间仅够最多作KK次调整(当然可以调整不满K次),所以这个问题交给了你。

    输入格式

    第一行包含2个正整数N与K,表示了序列长度与最多交换次数。

    第二行包含了一个长度为N的字符串,字符串仅由字母“j”与字母“z”组成,描述了这个序列。

    输出格式

    一个非负整数,为调整最多K次后最后最多能出现多少个“jz”子串。

    输入输出样例

    输入 #1 复制

    5 2
    zzzjj

    输出 #1 复制

    2

    说明/提示

    【样例说明】

    第1次交换位置1上的z和位置4上的j,变为jzzzj;

    第2次交换位置4上的z和位置5上的j,变为jzzjz。

    最后的串有2个“jz”子串。

    【数据规模与约定】

    对于10%的数据,有N≤10;

    对于30%的数据,有K≤10;

    对于40%的数据,有N≤50;

    对于100%的数据,有N≤500,K≤100。

    分析

    我们设(f[i][j][k][0])为遍历了字符串的前(i)位,改变了(j)(j)(k)(z),并且当前的这一位为(j)所能达到的最大价值

    (f[i][j][k][1])为遍历了字符串的前(i)位,改变了(j)(j)(k)(z),并且当前的这一位为(z)所能达到的最大价值

    我们先来考虑(f[i][j][k][0])

    如果该字符串的第(i)位本来是(z),那么我们把它改为(j)后,必定不会与前面的字符组成(jz),而且必定会花费一次修改操作

    因此当前的最大值应该在前面的字符变为(j)或变为(z)中取

    (f[i][j][k][0]=max(f[i-1][j][k-1][0],f[i-1][j][k-1][1]);)

    如果该字符串的第(i)位本来是(j),那么我们就不需要进行修改操作

    但是,当前的字符仍然不会与前面的字符组成(jz)

    所以当前的最大值还应该在前面的字符变为(j)或变为(z)中取

    (f[i][j][k][0]=max(f[i-1][j][k][0],f[i-1][j][k][1]);)

    接下来我们再考虑(f[i][j][k][1])

    如果该字符串的第(i)位本来是(z),那么如果上一位的字符为(j),那么又可以组成一个(jz),如果上一位为(j),则不能组成

    (f[i][j][k][1]=max(f[i-1][j][k][0]+1,f[i-1][j][k][1]);)

    如果该字符串的第(i)位本来是(j),那么我们就需要进行一次修改操作

    (f[i][j][k][1]=max(f[i-1][j-1][k][0]+1,f[i-1][j-1][k][1]);)

    最后我们再在(j)(k)相等的方案中取一个最大值即可

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=505,maxk=105;
    int n,m,f[maxn][maxk][maxk][3];
    char s[maxn];
    int main(){
        scanf("%d%d%s",&n,&m,s+1);
        memset(f,128,sizeof(f));
        f[0][0][0][1]=0;
        for(int i=1;i<=n;i++){
            for(int j=0;j<=m;j++){
                for(int k=0;k<=m;k++){
                    if(s[i]=='z'){
                        f[i][j][k][1]=max(f[i-1][j][k][0]+1,f[i-1][j][k][1]);
                        if(k) f[i][j][k][0]=max(f[i-1][j][k-1][0],f[i-1][j][k-1][1]);
                    } else {
                        f[i][j][k][0]=max(f[i-1][j][k][0],f[i-1][j][k][1]);
                        if(j) f[i][j][k][1]=max(f[i-1][j-1][k][0]+1,f[i-1][j-1][k][1]);
                    }
                }
            }
        }
        int ans=0;
        for(int i=0;i<=m;i++){
            ans=max(ans,max(f[n][i][i][1],f[n][i][i][0]));
        }
        printf("%d
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    Elasticsearch Query DSL 整理总结(三)—— Match Phrase Query 和 Match Phrase Prefix Query
    Elasticsearch Query DSL 整理总结(二)—— 要搞懂 Match Query,看这篇就够了
    Elasticsearch Query DSL 整理总结(一)—— Query DSL 概要,MatchAllQuery,全文查询简述
    Elasticsearch Java Rest Client API 整理总结 (三)——Building Queries
    Elasticsearch date 类型详解
    python 历险记(五)— python 中的模块
    python 历险记(四)— python 中常用的 json 操作
    python 历险记(三)— python 的常用文件操作
    Elasticsearch Java Rest Client API 整理总结 (二) —— SearchAPI
    Elasticsearch Java Rest Client API 整理总结 (一)——Document API
  • 原文地址:https://www.cnblogs.com/liuchanglc/p/13307426.html
Copyright © 2011-2022 走看看