[SCOI2007]壓縮(洛谷P2470)
阿新 • • 發佈:2018-06-23
pac nbsp -s ace def define target span 表示
壓縮
#include<iostream> #include<cstring> #include<cstdio> using namespace std; #define MAXN 55 #define INF 0x3f3f3f3f #define mid ((l+r)>>1) int n,f[MAXN][MAXN][2]; //不妨處理每個子串時,我們都在它的前面放一個M,最後答案長度-1即可 //f[l][r][0]表示子串[l,r]中除了前面的M,串中還存在其他的M的最短長度 //f[l][r][1]則表示只有前面一個M的最短長度 /* 三個轉移方程: 1.if(該串左右兩半相同) f[l][r][1]=min(f[l][r][1],f[l][mid][1]+1); 壓縮與不壓縮 2. i l~r-1 f[l][r][1]=min(f[l][r][1],f[l][i][1]+r-i); 3. i l~r-1 f[l][r][0]=min(f[l][r][0],min(f[l][i][0],f[l][i][1])+min(f[i+1][r][0],f[i+1][r][1]));*/ char s[MAXN]; int dp(int l,int r,bool op){ if(f[l][r][op]) return f[l][r][op]; if(l==r) return f[l][r][op]=2; int &d=f[l][r][op]=r-l+2; if(op){ bool flag=1; if((r-l+1)%2==1) flag=0; if(flag) for(int i=l;i<=mid;i++) if(s[i]!=s[mid+i-l+1]){ flag=0; break; } if(flag) d=min(d,dp(l,mid,1)+1); for(int i=l;i<r;i++) d=min(d,dp(l,i,1)+r-i); } else for(int i=l;i<r;i++) d=min(d,min(dp(l,i,0),dp(l,i,1))+min(dp(i+1,r,0),dp(i+1,r,1))); return d; } int main() { scanf("%s",s+1); n=strlen(s+1); dp(1,n,0); dp(1,n,1); printf("%d\n",min(f[1][n][0],f[1][n][1])-1); return 0; }
[SCOI2007]壓縮(洛谷P2470)