BZOJ 1068: [SCOI2007]压缩 区间DP

来源:互联网 发布:matlab矩阵相加 编辑:程序博客网 时间:2024/05/29 09:16

传送门
区间dp
这道题用记忆化搜索写起来更方便

    if(flag)        for(int i=l;i<r;i++)            ans=min(dp(l,i,1)+dp(i+1,r,1)+1,ans);

如果当前区间有M,那么可以枚举断点,压缩一下前面的,压缩一下后面的,中间加个M(记得+1O(∩_∩)O哈哈~)
然后也可以只压缩前面的
如果当前区间可以从中间劈开,切并且前后两段一样并且没有M的话说,就可以吧后面那一段视为R


代码如下:

#include<algorithm>#include<iostream>#include<cstring>#include<cstdio>#define inf 0x3f3f3f3fusing namespace std;const int maxn=50+5;char s[maxn];int len,f[maxn][maxn][2];bool check(int l,int r){    int lentemp=r-l+1,mid=(l+r)/2;    if(lentemp%2==1)        return false;    for(int i=l,j=mid+1;i<=mid;i++,j++)        if(s[i-1]!=s[j-1])            return false;    return true;}int dp(int l,int r,int flag){//flag=1---M is existed,flag=0---M is not existed    int ans=r-l+1;    if(ans==1)        return f[l][r][flag]=1;    if(f[l][r][flag]!=-1)        return f[l][r][flag];    if(flag)        for(int i=l;i<r;i++)            ans=min(dp(l,i,1)+dp(i+1,r,1)+1,ans);    for(int i=l;i<r;i++)        ans=min(dp(l,i,flag)+r-i,ans);//记得是flag,不是0,更不是1 >_< 感谢LTY Orz    if(check(l,r))        ans=min(ans,dp(l,(l+r)/2,0)+1);    return f[l][r][flag]=ans;}int main(){    scanf("%s",s),len=strlen(s),memset(f,-1,sizeof(f));//记得初始化(⊙o⊙)哦~~!!    cout<<dp(1,len,1)<<endl;        return 0;} 

by >o< neighthorn

0 0
原创粉丝点击