给一个由小写字母组成的字符串(len<=50)

我们可以用一种简单的方法来压缩其中的重复信息。

用M,R两个大写字母表示压缩信息 M标记重复串的开始,

R表示后面的一段字符串重复从上一个M到R之前的那一段。

(一开始字符串最前面有一个不用写出来的M)

来点神奇例子: abcabcdabcabcdxyxyz  abcRdRMxyRz  问压缩后的最短长度

【题解】

      ①区间DP。

      ②f[i][j][0/1]表示区间[i,j]中间是否填'M'

      状态转移的特点是拆分区间左边没M右边有M然后右边继续左右操作
      1).dp[l][r][0]=min{dp[l][r][0],dp[l][i][0]+r-i}  表示i~r不压缩

      2).如果区间长度(r-l+1)%2==0且前后两段字符相同(s[l~mid]==s[mid+1~r]) 

       dp[l][r][0]=min(dp[l][r][0],dp[l][mid][0]+1)  表示放一个R在mid和mid+1之间

      3).dp[l][r][1]=min{dp[l][r][1],min(dp[l][i][0],dp[l][i][1])+1+min(dp[i+1][r][0],dp[i+1][r][1])}       表示在i,i+1之间放一个M,那么l~i和i+1~r就是两个独立的区间了。

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
char s[55];
bool vis[55][55];
int dp[55][55][2],n;
bool check(int l,int m){
for(int i=0;l+i<m;i++)
if(s[l+i]!=s[m+i]) return 0;
return 1;
}
void dfs(int l,int r){
if(vis[l][r]) return;
vis[l][r]=1;
for(int i=l;i<r;i++) dfs(l,i),dfs(i+1,r);
int &ret0=dp[l][r][0],&ret1=dp[l][r][1];
ret0=ret1=r-l+1;
//1
for(int i=l;i<r;i++)
ret0=min(ret0,dp[l][i][0]+r-i);
//2
if((r-l+1)%2==0){
int mid=(l+r)>>1;
if(check(l,mid+1)) ret0=min(ret0,dp[l][mid][0]+1);
}
//3
for(int i=l;i<r;i++)
ret1=min(ret1,min(dp[l][i][0],dp[l][i][1])+1+min(dp[i+1][r][0],dp[i+1][r][1]));
}
int main(){
scanf("%s",s+1);
n=strlen(s+1);
dfs(1,n);
printf("%d",min(dp[1][n][0],dp[1][n][1]));
return 0;
}//*ZJ

.

【ZJ选讲·压缩】的更多相关文章

  1. 【ZJ选讲·字符串折叠】

    给一个字符串(len<=100) 把这个字符串折叠(就是压缩) 记 X(子串) 表示重复 X次该子串 比如 3(orz)  orzorzorz  来点神奇例子: AAAAAAAAAA ...

  2. 【ZJ选讲·画山】

    给出一张纸(N × M),你要在上面画山,但不能画出界(N,M<=100) Like this: 起点为(0,0),终点为(N,0) 给出w种线段画法(x,y),表示用了这种画法后,笔迹末 ...

  3. 【ZJ选讲·调整】

    给出n个点,m条有向边(带正权),起点S,终点T.(n<=2000,m<=30000) 再给出一个k,表示可以把最多k条边的权值调整为任意非负整数.(k<=100) 问是否可以通 ...

  4. 【ZJ选讲·钻石游戏】

    N×M的棋盘(M,N<=500)中,每个格子有一个颜色(颜色数1~9) P次操作(P<=1000),每次给出两个相邻的位置(保证颜色不同,两个格子有一条公共边),把这两个格子交换. 定 ...

  5. 【ZJ选讲·BZOJ 5073】

    小A的咒语 给出两个字符串A,B (len<=105) 现在可以把A串拆为任意段,然后取出不超过 x 段,按在A串中的前后顺序拼接起来 问是否可以拼出B串. [题解]       ①如果遇 ...

  6. 【ZJ选讲·BZOJ 5071】

    小A的数字 有一串数字A1 ,A2,--,An,每次可以进行如下骚操作: 选择一个数字i,将(Ai-1,Ai,Ai+1)变为(Ai-1+Ai,-Ai,Ai+1+Ai), (特别地,若i=N,则( ...

  7. DP选讲

    $DP$选讲直接上题吧放个题单[各省省选DP](https://www.luogu.com.cn/training/151079)$P5322[BJOI2019]$排兵布阵一眼题,考虑$dp[i][j ...

  8. PJ可能会用到的动态规划选讲-学习笔记

    PJ可能会用到的动态规划选讲-学习笔记 by Pleiades_Antares 难度和速度全部都是按照普及组来定的咯 数位状压啥就先不讲了 这里主要提到的都是比较简单的DP 一道思维数学巧题(补昨天) ...

  9. PJ考试可能会用到的数学思维题选讲-自学教程-自学笔记

    PJ考试可能会用到的数学思维题选讲 by Pleiades_Antares 是学弟学妹的讲义--然后一部分题目是我弄的一部分来源于洛谷用户@ 普及组的一些数学思维题,所以可能有点菜咯别怪我 OI中的数 ...

随机推荐

  1. C#5.0异步编程 HttpClient IP代理验证原码

    //访问HttpClient 代码 public async Task<string> VerifyProxy(string url, string proxy = "" ...

  2. ThinkPHP框架介绍

    什么是框架 php框架是许多代码的集合,这些代码的程序结构的代码(并不是业务代码)代码中有许多的函数,类,功能类包 不使用框架开发的缺陷 代码编写不规范 牵一发而动全身 不能很好满足客户各方面的需求 ...

  3. python中协程实现的本质以及两个封装协程模块greenle、gevent

    协程 协程,又称微线程,纤程.英文名Coroutine. 协程是啥 协程是python个中另外一种实现多任务的方式,只不过比线程更小占用更小执行单元(理解为需要的资源). 为啥说它是一个执行单元,因为 ...

  4. django之单表查询

    一.创建表 1.创建模型: 创建名为book的app,在book下的models.py中创建模型: from django.db import models # Create your models ...

  5. 剑指offer题目系列一

    本篇介绍<剑指offer>第二版中的四个题目:找出数组中重复的数字.二维数组中的查找.替换字符串中的空格.计算斐波那契数列第n项. 这些题目并非严格按照书中的顺序展示的,而是按自己学习的顺 ...

  6. python2.X与python3.X爬虫常用的模块变化对应

    python2 python3 import urllib2 import urllib.request,urllib.error import urllib.request,urllib.error ...

  7. Java8新特性(三)——Optional类、接口方法与新时间日期API

    一.Optional容器类 这是一个可以为null的容器对象.如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象. 查看结构图可以看到有如下常用方法: of(T)—— ...

  8. 20145202马超《JAVA》预备作业3

    虚拟机的安装[http://www.cnblogs.com/tuolemi/p/5861062.html] Linux命令[http://www.cnblogs.com/tuolemi/p/58781 ...

  9. 失败的尝试,使用继承扩展数组,以及ES6的必要性

    我们都知道直接在原生对象上扩展对象是很不好的.所以prototype这样的库广受非议. 一些库,比如lodash采用了工具包形式的扩展方式,绕开了对象的继承. 由于es6的class的出现,我尝试以A ...

  10. C++学习013多态

    何为多态 面向对象最要的特征之一就是多态,而纯虚函数是实现多态的主要方式.它可以提供一个通过用的接口,同样调用一个方法, 由于运算对象不同,方法也不同,这也就是所谓的动态绑定. #include &l ...