【DP 训练】Folding, ACM/ICPC NEERC 2002, UVa1630
来源:互联网 发布:手机称重软件 编辑:程序博客网 时间:2024/05/19 09:01
基于dp的字符串压缩
思路:首先是要找相同的字符串组,然后进行标记。就着上面的例子是, NEEEEERYESYESYESNEEEEERYESYESYES,变成 2个 NEEEEERYESYESYES,然后里面再变成N5(E)R3(YES),这么一看,似乎就是把这个大的字符串拆成小的字符串进行结合,类似于分治的思想。而且这个题目有最优子结构,对于每个可以合并的串,一定要使用最短的结合方式,否则整个结果一定不是最短的。
于是DP的方程就得到了 dp[ i ][ j ]=min(dp[ i ][ j ],dp[ i ][ k ]+dp[ k+1 ][ j ]) dp[ i ][ j ] 从i到j代表 从i到j 的子字符串长度
首先用一个string的二位数组,把从i到j的最小字符串存下来,然后首先遍历字符串,找出所有长度一样的字符串组,用一个二维数组save进行标记。
例如
NEEEEEEERYESYESYESNEEEEEEERYESYESYES
我们发现(下标从1开始) 2~8位是长度为1的字符串组 所以标记save[2][8]=7; (7是字字符串个数)
别忘了更新类似于save[3][8]=6;这种的。在这时候对于这个字符串,一定要取最短的结合方式(最优子结构)
#include<bits/stdc++.h>using namespace std;string str;int dp[110][110];string fold[110][110];int len;const int INF = 1e9;int zip(int L,int R)//压缩函数 输入保证了L<R {//@return: 循环节长度 for(int i=1;i<=(R-L+1)/2;i++)//枚举循环长度 {if((R-L+1)%i)continue; bool flag = true;for(int j=L;j+i<=R;j++){if(str[j]!=str[j+i]){flag = false;break;}}if(flag)return i;}return 0;}int sol(int L,int R){if(dp[L][R]!=-1)return dp[L][R];if(L==R){dp[L][R] = 1;fold[L][R] = str[L];return 1;}int ret = INF,k;for(int i=L;i<R;i++){int tmp = sol(L,i)+sol(i+1,R);if(tmp<ret){k = i;ret = tmp;}}fold[L][R] = fold[L][k]+fold[k+1][R];ret = sol(L,k)+sol(k+1,R);int tlen = zip(L,R);//对重复串进行压缩 if(tlen){bool flag = true;for(int i=L;i<=R;i++)if(str[i]=='('||str[i]==')')flag = false;char t[10];sprintf(t,"%d",(R-L+1)/tlen);string nstr = t+string("(")+fold[L][L+tlen-1]+string(")");if(flag&&nstr.size()<ret){ret = nstr.size();fold[L][R] = nstr;}}dp[L][R] = ret;return ret;}int main(void){ios::sync_with_stdio(false);while(cin>>str){memset(dp,-1,sizeof(dp));len = str.size();sol(0,len-1);cout<<fold[0][len-1]<<endl;}return 0;}
1 0
- 【DP 训练】Folding, ACM/ICPC NEERC 2002, UVa1630
- [DP记忆化 字符串] UVa1630 Folding
- UVA1630 - Folding
- 2014-2015 ACM-ICPC, NEERC K Kebab House(dp)
- 2016-2017 ACM-ICPC, NEERC, Southern Subregional Contest J dp
- UVA1630[Folding] 区间动态规划
- UVa1630 Folding 记忆化搜索
- 2015-2016 ACM-ICPC, NEERC, Moscow Subregional Contest H题: Hashing [基础DP]
- 2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest Problem J 【二分+DP+单调队列】
- Codeforces 730 J. Bottles DP 0-1背包- 2016-2017 ACM-ICPC, NEERC, Southern Subregional Contest
- 2016-2017 ACM-ICPC, NEERC, Southern Subregional Contest - J. Bottles(DP)
- UVa1630 Folding/poj 2176 Folding/zoj 1554 Folding
- Box, ACM/ICPC NEERC 2004, UVa1587
- Kickdown, ACM/ICPC NEERC 2006, UVa 1588
- UVA 1587 Box 【ACM/ICPC NEERC 2004】
- 2017-2018 ACM-ICPC, NEERC解题报告
- Box, ACM/ICPC NEERC 2004, UVa1587
- Kickdown, ACM/ICPC NEERC 2006, UVa1588
- 如何灵活运用Linux 进程资源监控和进程限制
- 安卓程序oom(内存溢出)的问题
- 总结六条对我们学习Linux系统有用的忠告
- 全选反选
- Matlab debug技巧
- 【DP 训练】Folding, ACM/ICPC NEERC 2002, UVa1630
- PHP全排序算法
- 欧几里德与扩展欧几里德算法
- OPENGL ES总结
- 应用大数据和机器学习技术实现车险全流程智能化的方案(上)
- 第五周-c语言 oj(1992)
- hdu 5926/ Mr. Frog’s Game
- php 判断数组是否为空的几种方法
- PHP学习笔记八之字符串(进阶篇)