zoukankan      html  css  js  c++  java
  • 【u122】迎接仪式

    Time Limit: 1 second
    Memory Limit: 128 MB

    【问题描述】
    LHX教主要来X市指导OI学习工作了。为了迎接教主,在一条道路旁,一群Orz教主er穿着文化衫站在道路两旁迎接教主,每件文化衫上都印着大
    字。一旁的Orzer依次摆出“欢迎欢迎欢迎欢迎……”的大字,但是领队突然发现,另一旁穿着“教”和“主”字文化衫的Orzer却不太和谐
    。 为了简单描述这个不和谐的队列,我们用“j”替代“教”,“z”替代“主”。而一个“j”与“z”组成的序列则可以描述当前的队列。为了让
    教主看得尽量舒服,你必须调整队列,使得“jz”子串尽量多。每次调整你可以交换任意位置上的两个人,也就是序列中任意位置上的两个
    字母。而因为教主马上就来了,时间仅够最多作K次调整(当然可以调整不满K次),所以这个问题交给了你。

    【输入格式】

    输入文件welcome.in的第1行包含2个正整数N与K,表示了序列长度与最多交换次数。 第2行包含了一个长度为N的字符串,字符串仅由字母“j”与字母“z”组成,描述了这个序列。

    【输出格式】

    输出文件welcome.out仅包括一个非负整数,为调整最多K次后最后最多能出现多少个“jz”子串。
    【数据规模】

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

    Sample Input1

    5 2
    zzzjj

    Sample Output1

    2

    【样例说明】

    第1次交换位置1上的z和位置4上的j,变为jzzzj;
    第2次交换位置4上的z和位置5上的j,变为jzzjz。
    最后的串有2个“jz”子串。

    【题目链接】:http://noi.qz5z.com/viewtask.asp?id=u122

    【题解】

    把j和z转换成0和1;
    则原问题等价于,在字符串里面进行小于k次操作;
    使得字符串中子串”01”的个数达到最大;
    j和z的交换可以看成是把1变成0和0变成1的过程;
    设f[i][x][y]表示前i个字符里面经过了x次0变成1,y次1变成0的过程所得到的最大”01”子串个数;
    可以枚举i-1,i这两个位置的字符要不要变成01子串,即s[i-1]变成0,s[i]变成1;
    这样问题就转换成前i-2个字符的问题了;
    至于f[i-2][][]中的2、3维是什么状态,就根据i-1和i的情况来确定:
    因为枚举了所有的i-1和i是01子串的情况。所以能够考虑到所有情况;
    最后在f[n][i][i]中找答案就可以了;表示0和1的转换次数一样->相当于交换;
    其次往前转移的时候,f[i-2][][]的这个状态必须要存在才行;不然会造成错解;
    比如f[3][4][4];则必须先有f[3][4][3]的状态或f[3][3][3],f[3][3][4]的状态;
    不能直接从f[3][0][0]跳到f[3][4][4];

    【完整代码】

    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <set>
    #include <map>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    #include <vector>
    #include <stack>
    #include <string>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define pb push_back
    #define fi first
    #define se second
    
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pll;
    
    void rel(LL &r)
    {
        r = 0;
        char t = getchar();
        while (!isdigit(t) && t!='-') t = getchar();
        LL sign = 1;
        if (t == '-')sign = -1;
        while (!isdigit(t)) t = getchar();
        while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
        r = r*sign;
    }
    
    void rei(int &r)
    {
        r = 0;
        char t = getchar();
        while (!isdigit(t)&&t!='-') t = getchar();
        int sign = 1;
        if (t == '-')sign = -1;
        while (!isdigit(t)) t = getchar();
        while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
        r = r*sign;
    }
    
    const int MAXN = 500+10;
    const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
    const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
    const double pi = acos(-1.0);
    
    int n,k;
    char s[MAXN];
    int a[MAXN];
    int f[MAXN][100+10][100+10];
    
    int main()
    {
       // freopen("F:\rush.txt","r",stdin);
        rei(n);rei(k);
        scanf("%s",s+1);
        rep1(i,1,n)
            if (s[i]=='j')
                a[i] = 0;
            else
                a[i] = 1;
        memset(f,255,sizeof(f));
        int t = min(n,k);
        f[0][0][0] = 0;
        f[1][0][0] = 0;
        if(a[1]==1)
            f[1][0][1]=0;
        if(a[1]==0)
            f[1][1][0]=0;
        rep1(i,2,n)
            rep1(x,0,min(i,k))
                rep1(y,0,min(i,k))
                    {
                        f[i][x][y]=f[i-1][x][y];
                        if (a[i]==0)
                        {
                            if (a[i-1]==1)
                            {
                                if (x>0 && y>0 && f[i-2][x-1][y-1]!=-1)
                                    f[i][x][y] = max(f[i][x][y],f[i-2][x-1][y-1]+1);
                            }
                            if (a[i-1]==0)
                            {
                                if (x>0 && f[i-2][x-1][y]!=-1)
                                    f[i][x][y] = max(f[i][x][y],f[i-2][x-1][y]+1);
                            }
                        }
                        if (a[i]==1)
                        {
                             if (a[i-1]==0)
                            {
                                if (f[i-2][x][y]!=-1)
                                    f[i][x][y] = max(f[i][x][y],f[i-2][x][y]+1);
                            }
                            if (a[i-1]==1)
                            {
                                if (y>0 && f[i-2][x][y-1]!=-1)
                                    f[i][x][y] = max(f[i][x][y],f[i-2][x][y-1]+1);
                            }
                        }
                    }
        int ans = 0;
        rep1(i,0,k)
            ans = max(ans,f[n][i][i]);
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    linux上java和golang环境变量的设置
    MySQL踩坑及MySQL解压版安装
    Mysql踩坑 自动更新的时间只允许有一个
    从零开始学习PYTHON3讲义(十五)让画面动起来
    从零开始学习PYTHON3讲义(十四)写一个mp3播放器
    从零开始学习PYTHON3讲义(十三)记事本的升级版:网络记事本
    从零开始学习PYTHON3讲义(十二)画一颗心送给你
    从零开始学习PYTHON3讲义(十一)计算器升级啦
    从零开始学习PYTHON3讲义(十)自己做一个“电子记事本”
    从零开始学习PYTHON3讲义(九)字典类型和插入排序
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626909.html
Copyright © 2011-2022 走看看