BZOJ 1090 字符串折叠(区间DP)
2016-06-02 17:43
357 查看
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1090
题意:字符串AAAAAAAAAABABABCCD的最短折叠为9(A)3(AB)CCD,注意数字的长度和圆括号都算最后长度。求一种折叠方式使得总长度最小。
思路:记忆化搜索。
题意:字符串AAAAAAAAAABABABCCD的最短折叠为9(A)3(AB)CCD,注意数字的长度和圆括号都算最后长度。求一种折叠方式使得总长度最小。
思路:记忆化搜索。
#include<algorithm> #include<cstdio> #include<cmath> #include<cstring> #include<iostream> char s[500005],a[500005]; int f[5005][5005]; bool ok(int l,int r,int len){ int L=0; for (int i=l;i<=l+len-1;i++) a[++L]=s[i]; int num=(r-l+1)/len; for (int i=1;i<=num;i++) for (int j=1;j<=len;j++) if (a[j]!=s[l+(i-1)*len+j-1]) return 0; return 1; } int cal(int x){ if (x<10) return 1; if (x<=99) return 2; return 3; } int dp(int l,int r){ if (f[l][r]!=-1) return f[l][r]; if (l==r) return 1; int len=r-l+1; f[l][r]=len; for (int i=l;i<r;i++) f[l][r]=std::min(f[l][r],dp(l,i)+dp(i+1,r)); for (int i=1;i<len;i++) if (len%i==0&&ok(l,r,i)) f[l][r]=std::min(f[l][r],dp(l,l+i-1)+cal(len/i)+2); return f[l][r]; } int main(){ scanf("%s",s+1); int n=strlen(s+1); for (int i=1;i<=n;i++) for (int j=1;j<=n;j++) f[i][j]=-1; printf("%d\n",dp(1,n)); }
相关文章推荐
- 《实例化需求》读书笔记
- java获得当前文件路径
- JNI各类型参数互相调用
- (NGUI)label设置局部字体大小
- SSH远程登录配置文件sshd_config详解
- Linux常用命令:find命令之xargs
- 如何简单理解ngnix的反向代理
- POJ 1067 取石子游戏
- python装饰器
- 获取鼠标点击处的控件并获取其坐标(对控制控件和绘制控件都很实用)
- 堆排序Heap sort
- svn: resource out of date; try updating的解决
- Ubuntu django psycopg2 problem
- jdbc实现对CLOB和BLOB数据类型操作
- 定时器
- C#中using的三种用法
- 常见问题
- 浅析mongodb中group分组
- Linux常用命令:find命令之exec
- 项目的结构