首页 > 代码库 > Vijos1616 迎接仪式

Vijos1616 迎接仪式

描述

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

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

格式

输入格式

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

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

输出格式

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

样例1

样例输入1

5 2
zzzjj

样例输出1

2

限制

对于10%的数据,有N≤10;
对于30%的数据,有K≤10;
对于40%的数据,有N≤50;
对于100%的数据,有N≤500,K≤100。

时限1s。

提示

第1次交换位置1上的z和位置4上的j,变为**jz**zzj;
第2次交换位置4上的z和位置5上的j,变为**jz**z**jz**。

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

 

【分析】

线性dp入门, dp[i][j][k]表示至第i位为止调换了j个‘j’和k个‘z’所得到的‘jz’串的最大个数, 每次只考虑s[i]和s[i-1]即可,只有‘jz‘‘jj‘‘zz‘‘zj‘四种情况,方程还算好写。

需要注意的是初始化。

一开始一直70分,de了半天bug也没改对,怒重敲一遍就AC了,发现有一个s[i]写成s[i-1]了...还是要细心啊。

注:似乎需要记录一下j和z的个数,然后ans取三者的最小值?之前的错误代码里加了,不过重敲的时候没加也过了。

 

【代码】

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

char s[505];
int dp[505][105][105];
int n, m, ans;

int main() {
    cin >> n >> m;
    scanf("%s", s+1);
    for (int i=0;i<=500;++i)
        for (int j=0;j<=100;++j)
            for (int k=0;k<=100;++k)
                dp[i][j][k]=-0x7fffffff;
    dp[0][0][0]=dp[1][0][0]=0;
    if (s[1]==j)
        dp[1][1][0]=0;
    else
        dp[1][0][1]=0;
    for (int i=2;i<=n;++i)
        for (int j=0;j<=m;++j)
            for (int k=0;k<=m;++k) {
                dp[i][j][k]=dp[i-1][j][k];
                if (s[i-1]==j && s[i]==z)
                    dp[i][j][k]=max(dp[i][j][k], dp[i-2][j][k]+1);
                if (s[i-1]==j && s[i]==j && j)
                    dp[i][j][k]=max(dp[i][j][k], dp[i-2][j-1][k]+1);
                if (s[i-1]==z && s[i]==z && k)
                    dp[i][j][k]=max(dp[i][j][k], dp[i-2][j][k-1]+1);
                if (s[i-1]==z && s[i]==j && j && k)
                    dp[i][j][k]=max(dp[i][j][k], dp[i-2][j-1][k-1]+1);
                if (j==k)
                    ans=max(ans, dp[i][j][k]);
            }
    cout << ans << endl;
}

 

Vijos1616 迎接仪式