【题解】

  区间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. 洛谷 P2577 [ ZJOI 2005 ] 午餐 —— DP + 贪心

    题目:https://www.luogu.org/problemnew/show/P2577 首先,想一想可以发现贪心策略是把吃饭时间长的人放在前面: 设 f[i][j] 表示考虑到第 i 个人,目前 ...

  2. easyui 生成tas方式

    1.采用<a>标签形式 <div id="tabs" style="width:100%;"> <ul> <li id ...

  3. Angular学习日记(一) 开发环境的搭建

    从看视频到自己尝试,总会走很多的弯路才能成功. 首先:装最新版的nodejs. 第一种:使用npm安装 首先设置taobao镜像,npm config set registry https://reg ...

  4. Postgresql的一些命令

    显示所有数据表: \dt 显示表结构:  \d YOUR_TABLE 进入数据库: psql DATABASE_NAME 显示所有数据库: \list 退出: \q 删除数据库: dropdb DAT ...

  5. 为什么JavaWeb项目要分层

    首先让我们坐着时光机回到n年前的web开发.那个时候最早都是静态的html页面,后来有了数据库,有了所谓的动态页面,然后程序猿在编码的时候,会把所有的代码都写在页面上,包括数据库连接,包括事务控制,接 ...

  6. bzoj 1044: [HAOI2008]木棍分割【二分+dp】

    对于第一问二分然后贪心判断即可 对于第二问,设f[i][j]为已经到j为止砍了i段,转移的话从$$ f[i][j]=\sigema f[k][j-1] (s[j]-s[k-1]<=ans) 这里 ...

  7. bzoj 2662: [BeiJing wc2012]冻结【分层图+spfa】

    死活想不到分层图emmm 基本想法是建立分层图,就是建k+1层原图,然后相邻两层之间把原图的边在上一层的起点与下一层的终点连起来,边权为val/2,表示免了这条边的边权,然后答案就是第0层的s到k层的 ...

  8. poj 3613 Cow Relays【矩阵快速幂+Floyd】

    !:自环也算一条路径 矩阵快速幂,把矩阵乘法的部分替换成Floyd(只用一个点扩张),这样每"乘"一次,就是经过增加一条边的最短路,用矩阵快速幂优化,然后因为边数是100级别的,所 ...

  9. [SDOI2011]消防(单调队列,树的直径,双指针)

     消防 2011年  时间限制: 2 s  空间限制: 256000 KB  题目等级 : 大师 Master   题目描述 Description 某个国家有n个城市,这n个城市中任意两个都连通且有 ...

  10. hexo简易脚本

    !/bin/bash 检查是否为master分支.目录是否正确 function git-branch-name { git symbolic-ref --short -q HEAD } functi ...