zoukankan      html  css  js  c++  java
  • [SCOI2007]压缩(区间dp)

    神仙题,看了半天题解才看明白。。。

    因为题目里说如果没有m,会自动默认m在最前面。

    我们设计状态为dp[l][r][0/1]为在区间l到r中有没有m的最小长度。

    转移:枚举我们要压缩的起点,dp[l][i][1]+dp[i+1][r][1]+1,加一是指我们要压缩后半段,在断点处加上一个m。

    如果我们不压缩后半段,那转移就为dp[l][i][1]+r-i,因为后面不动,就直接加上。

    如果发现它可以压缩,直接dp[l][mid][0]+1,注意tag为0。

    Code

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define N 55
    using namespace std;
    int dp[N][N][2],n;
    char s[N];
    inline bool pd(int l,int r){
        if((r-l+1)%2==1)return 0;
        int len=(r-l+1)/2;
        for(int i=l;i<=l+len-1;++i)
          if(s[i]!=s[i+len])return 0;
         return 1; 
    }
    int dfs(int l,int r,int tag){
        if(dp[l][r][tag])return dp[l][r][tag];
        int ans=r-l+1;
        if(ans==1)return ans;
        if(tag)
          for(int i=l;i<r;++i)ans=min(ans,dfs(l,i,1)+1+dfs(i+1,r,1));
        for(int i=l;i<r;++i)ans=min(ans,dfs(l,i,tag)+r-i);
        if(pd(l,r))ans=min(ans,dfs(l,(l+r)>>1,0)+1);
        return dp[l][r][tag]=ans; 
    }
    int main(){
        scanf("%s",s);
        n=strlen(s);
        printf("%d",dfs(0,n-1,1)); 
        return 0;
    } 
  • 相关阅读:
    快速幂
    1112个人赛,最长回文串常见算法讨论
    11-05-sdust-个人赛赛后随想
    UVA 1149 Bin Packing
    UVa 1608,Non-boring sequences
    UVa 10954,Add All
    UVa 714,Copying Books
    Careercup
    Careercup
    Careercup
  • 原文地址:https://www.cnblogs.com/ZH-comld/p/9695881.html
Copyright © 2011-2022 走看看