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;
    }
    
  • 相关阅读:
    Activity
    python 执行DOS/CMD命令
    MyISAM存储引擎的表级锁定优化
    vbs隐藏cmd窗口
    文件操作一
    Java基础知识
    Linux下利用.htaccess建立多站点
    python使用WMI监视系统-CPU使用率
    python操作mysql数据库注意
    类集框架(二)
  • 原文地址:https://www.cnblogs.com/liuchanglc/p/13307426.html
Copyright © 2011-2022 走看看