【u122】迎接仪式

来源:互联网 发布:涉密网络分级保护 编辑:程序博客网 时间:2024/05/17 03:08

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 secondtypedef 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\n",ans);    return 0;}
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 2个月的婴儿咳嗽怎么办 2个月的宝宝干咳怎么办 2月宝宝感冒咳嗽怎么办 产妇肚子上长小疙瘩很痒怎么办 泰迪生下小狗不吃奶怎么办? 刚生的狗不吃奶怎么办 刚出生的小牛不吃奶怎么办 吃奶的狗崽拉稀怎么办 新生儿吃奶老是呛到怎么办 刚生小狗不吃奶怎么办 刚出生的小羊不吃奶怎么办 羔羊走路不稳不吃奶怎么办 新生儿喝奶老是呛到怎么办 宝宝吃母乳呛到怎么办 宝宝一直睡觉不吃奶怎么办 3个月婴儿不吃奶怎么办 新生婴儿晚上不睡觉怎么办 宝宝肚子胀不吃奶怎么办 宝宝25天不睡觉怎么办 50天婴儿不吃奶怎么办 儿子关在房间玩电脑怎么办? 宽带拨号上网账号密码忘了怎么办 双眼皮割的太宽怎么办 营业执照异常名录移除注销怎么办 工商局注册后骚扰电话怎么办 单位工作失误医保断交7年怎么办 大门对大门怎么办?巧用天官赐福 委托书公司名称打错了怎么办 招行ubank不对账怎么办 信贷公司利息高不合理怎么办 衣服上的logo掉怎么办 ui设计师接不到私活怎么办 微信打开很慢怎么办 小泰迪感冒加身上结痂怎么办 法斗眼睛肿了怎么办 地图鱼身上有白点怎么办 人被广告牌砸了怎么办 小米手机出现繁体中文英文怎么办 雅思考试把姓名写错了怎么办 房贷的流水账假怎么办 报到证报道期限过期了怎么办