【题解】

  区间DP.  设f[i][j]表示i~j的最小代价。再枚举中间点k,很容易想到转移方程为f[i][j]=min(f[i][j],f[i][k]+f[k][j]),同时如果i~k可以通过重复获得i~j,那么f[i][j]=min(f[i][j],f[i][k]+len(x)+2),这里的len(x)是指重复次数在十进制下有多少位。

 #include<cstdio>
#include<algorithm>
#include<cstring>
#define LL long long
#define rg register
#define N 200
using namespace std;
int n,m,f[N][N];
char s[N];
inline int read(){
int k=,f=; char c=getchar();
while(c<''||c>'')c=='-'&&(f=-),c=getchar();
while(''<=c&&c<='')k=k*+c-'',c=getchar();
return k*f;
}
inline bool check(int l,int r,int end){
int l1=r-l+,l2=end-l+;
if(l2%l1) return ;
m=l2/l1;
for(rg int i=;i<=m;i++){
int st=l+(i-)*l1;
for(rg int j=;j<l1;j++) if(s[l+j]!=s[st+j]) return ;
}
return ;
}
inline int qlen(int x){
int cnt=;
while(x){
x/=;
cnt++;
}
return cnt;
}
int main(){
scanf("%s",s+); n=strlen(s+);
for(rg int i=;i<=n;i++)
for(rg int j=i;j<=n;j++) f[i][j]=j-i+;
for(rg int l=;l<=n;l++){
for(rg int i=;i+l-<=n;i++){
int j=i+l-;
for(rg int k=i;k<=j;k++){
f[i][j]=min(f[i][j],f[i][k]+f[k+][j]);
if(check(i,k,j)){
f[i][j]=min(f[i][j],f[i][k]++qlen(m));
// printf("%d %d %d\n",i,k,j);
}
}
}
}
printf("%d\n",f[][n]);
return ;
}

  输出方案的版本。

 #include<cstdio>
#include<algorithm>
#include<cstring>
#define LL long long
#define rg register
#define N 200
using namespace std;
int n,m,f[N][N],ans[N],from[N][N];
char s[N];
inline int read(){
int k=,f=; char c=getchar();
while(c<''||c>'')c=='-'&&(f=-),c=getchar();
while(''<=c&&c<='')k=k*+c-'',c=getchar();
return k*f;
}
inline bool check(int l,int r,int end){
int l1=r-l+,l2=end-l+;
if(l2%l1) return ;
m=l2/l1;
for(rg int i=;i<=m;i++){
int st=l+(i-)*l1;
for(rg int j=;j<l1;j++) if(s[l+j]!=s[st+j]) return ;
}
return ;
}
inline int qlen(int x){
int cnt=;
while(x){
x/=;
cnt++;
}
return cnt;
}
void out(int l,int r){
if(f[l][r]==r-l+){
for(rg int i=l;i<=r;i++) printf("%c",s[i]);
return;
}
int k=from[l][r];
if(check(l,k,r)){
printf("%d(",m);
out(l,k);
printf(")");
}
else{
out(l,k); out(k+,r);
}
}
int main(){
while(scanf("%s",s+)!=EOF){
n=strlen(s+);
for(rg int i=;i<=n;i++)
for(rg int j=i;j<=n;j++) f[i][j]=j-i+;
for(rg int l=;l<=n;l++){
for(rg int i=;i+l-<=n;i++){
int j=i+l-;
for(rg int k=i;k<=j;k++){
if(f[i][k]+f[k+][j]<f[i][j]){
f[i][j]=f[i][k]+f[k+][j];
from[i][j]=k;
}
if(check(i,k,j)){
int tmp=f[i][k]++qlen(m);
if(tmp<f[i][j]){
f[i][j]=tmp;
from[i][j]=k;
}
// printf("%d %d %d\n",i,k,j);
}
}
}
}
out(,n);
puts("");
}
// printf("%d\n",f[1][n]);
return ;
}

洛谷 4302 BZOJ 1090 SCOI2003 字符串折叠 UVA1630 Folding(输出方案版)的更多相关文章

  1. BZOJ 1090: [SCOI2003]字符串折叠 区间DP

    1090: [SCOI2003]字符串折叠 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/p ...

  2. bzoj 1090 [SCOI2003]字符串折叠(区间DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1090 [题意] 给定一个字符串,问将字符串折叠后的最小长度. [思路] 设f[i][j ...

  3. BZOJ 1090: [SCOI2003]字符串折叠

    Sol 区间DP. 转移很简单,枚举会形成的断长转移就行,话说上一题我就跟这个是差不多的思路,转移改了改,然后死活过不了... 同样都是SCOI的题...相差4年... Code /********* ...

  4. bzoj 1090: [SCOI2003]字符串折叠【区间dp】

    设f[i][j]为区间(i,j)的最短长度,然后转移的话一个是f[i][j]=min(j-i+1,f[i][k]+f[k+1][j]),还有就是把(k+1,j)合并到(i,k)上,需要判断一下字符串相 ...

  5. 【BZOJ】1090: [SCOI2003]字符串折叠(dp)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1090 随便yy一下.. 设f[i,j]表示i-j的最小长度 f[i, j]=min{j-i+1, f ...

  6. 1090. [SCOI2003]字符串折叠【区间DP】

    Description 折叠的定义如下: 1. 一个字符串可以看成它自身的折叠.记作S  S 2. X(S)是X(X>1)个S连接在一起的串的折叠.记作X(S)  SSSS…S(X个S). ...

  7. BZOJ1090: [SCOI2003]字符串折叠

    区间dp. 一种是分段dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]); 一种是这一段可以缩写dp[i][j]=min(dp[i][j],dp[i][l]+2+ca ...

  8. 【BZOJ1090】[SCOI2003]字符串折叠(动态规划)

    [BZOJ1090][SCOI2003]字符串折叠(动态规划) 题面 BZOJ 洛谷 题解 区间\(dp\).设\(f[i][j]\)表示压缩\([i,j]\)区间的最小长度.显然可以枚举端点转移.再 ...

  9. 洛谷 P3370 【模板】字符串哈希

    洛谷 P3370 [模板]字符串哈希 题目描述 如题,给定N个字符串(第i个字符串长度为Mi,字符串内包含数字.大小写字母,大小写敏感),请求出N个字符串中共有多少个不同的字符串. 友情提醒:如果真的 ...

随机推荐

  1. Java中的经典算法之冒泡排序

    原理:比较两个相邻的元素,将值大的元素交换至右端. 思路:依次比较相邻的两个数,将小数放在前面,大数放在后面.即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后.然后比较第2个数和第3个数,将 ...

  2. 云服务器装teamviewer

    [int32] EulaAccepted = 1 [int32] EulaAcceptedRevision = 6

  3. INT类型知多少

    前言: 整型是MySQL中最常用的字段类型之一,通常用于存储整数,其中int是整型中最常用的,对于int类型你是否真正了解呢?本文会带你熟悉int类型相关知识,也会介绍其他整型字段的使用. 1.整型分 ...

  4. 编写第一Spring程序

    构建Spring项目 通过https://start.spring.io/来构建项目,在这里我选择了两个依赖,web 和 Actuator. 项目结构 通过eclipse导入项目,可以看到这是一个标准 ...

  5. 整数类型c++

    数据类型 定义标识符 占字节数 数值范围 数值范围 短整型 short [int] 2(16位) -32768-32767 -215-215-1 整型 [long] int 4(32位) -21474 ...

  6. 一个完整的mybatis项目,包含增删改查

    1.导入jar包,导入相关配置文件,均在自己博客园的文件中 编写mybatis.xml文件 <?xml version="1.0" encoding="UTF-8& ...

  7. 409 Longest Palindrome 最长回文串

    给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串.在构造过程中,请注意区分大小写.比如 "Aa" 不能当做一个回文字符串.注意:假设字符串的长度不会超过 ...

  8. 在dataGridView空间中添加数据

    //查询信息sql语句 string sql = "select studentName,addres from student"; SqlDataAdapter adapter ...

  9. mac当你有多个版本的命令存在是怎么使用最新版本

    例如你安装了一个最新的git.然而系统中由于xcode等自带的git的存在.使得/usr/bin/git 是xcode的版本. 只需要再 ~/.bash_profile 中添加一行优先path即可 e ...

  10. jQuery中$this和$(this)的区别

    要写一个点击弹窗任意地方,关闭弹窗.点击事件写标签在元素上 onclick =  closepop(this),这时候很容易搞不清楚怎么去获取当前元素 function closepop(e){ va ...