首页 > 代码库 > bzoj1090:[SCOI2003]字符串折叠
bzoj1090:[SCOI2003]字符串折叠
思路:区间dp,令f[l][r]表示l到r的答案,于是f[l][r]=min(f[l][mid],f[mid+1][r]),如果能折叠f[l][r]=min(f[l][r],f[l][l+len-1]+calc(r-l+1,len),calc是计算数字的长度。记忆化搜索即可。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 8 char s[105]; 9 int f[105][105];10 11 bool check(int l,int r,int len){12 for (int i=l;;i+=len){13 if (i+len>r) break;14 for (int j=i;j<=i+len-1;j++)15 if (s[j]!=s[j+len] && j+len<=r) return 0;16 }17 return 1;18 }19 20 int calc(int n,int len){21 int ans=0;n/=len;while (n) n/=10,ans++;return ans; 22 }23 24 int dp(int l,int r){25 if (l==r) return f[l][r]=1;26 if (f[l][r]) return f[l][r];27 int len=r-l+1;f[l][r]=r-l+1;28 for (int mid=l;mid<r;mid++) f[l][r]=min(f[l][r],dp(l,mid)+dp(mid+1,r));29 for (int L=1;L<len;L++) if (len%L==0 && check(l,r,L)) f[l][r]=min(f[l][r],dp(l,l+L-1)+2+calc(len,L));30 return f[l][r];31 }32 33 int main(){34 scanf("%s",s+1);35 printf("%d",dp(1,strlen(s+1)));36 return 0;37 }
bzoj1090:[SCOI2003]字符串折叠
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。