dp——洛谷P1136 迎接仪式

来源:互联网 发布:js如何获取子元素内容 编辑:程序博客网 时间:2024/05/11 17:53

https://www.luogu.org/problem/show?pid=1136
玄学dp
首先我们发现这道题有些奇怪的性质

交换k次,其实意味着k个j变成z,k个z变成j。

而且每个字最多交换一次;
但是一次交换,有可能对答案的贡献+1
也有可能+2;
这个怎么办呢?
f[i][j][k]
表示前i个里面,’j’变成’z’ j次
‘z’变成’j’ k次;
通过s[i]和s[i-1]更新
当i==k的时候更新答案;
然后预处理要小心

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>using namespace std;int f[505][105][105];int n,m,ans;char c[505];int main(){    scanf("%d%d",&n,&m);    scanf("%s",c+1);    memset(f,-63,sizeof f);    f[0][0][0]=f[1][0][0]=0;    if(c[1]=='j')f[1][1][0]=0;else f[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++){                if(c[i-1]=='j'&&c[i]=='z')f[i][j][k]=f[i-2][j][k]+1;                if(c[i-1]=='j'&&c[i]=='j'&&j)f[i][j][k]=f[i-2][j-1][k]+1;                if(c[i-1]=='z'&&c[i]=='z'&&k)f[i][j][k]=f[i-2][j][k-1]+1;                if(c[i-1]=='z'&&c[i]=='j'&&j&&k)f[i][j][k]=f[i-2][j-1][k-1]+1;                f[i][j][k]=max(f[i][j][k],f[i-1][j][k]);                if(k==j)ans=max(ans,f[i][j][k]);            }    printf("%d",ans);}
原创粉丝点击