zoukankan      html  css  js  c++  java
  • 1068: [SCOI2007]压缩

    Description

    给一个由小写字母组成的字符串,我们可以用一种简单的方法来压缩其中的重复信息。压缩后的字符串除了小写字母外还可以(但不必)包含大写字母R与M,其中M标记重复串的开始,R重复从上一个M(如果当前位置左边没有M,则从串的开始算起)开始的解压结果(称为缓冲串)。 bcdcdcdcd可以压缩为bMcdRR,下面是解压缩的过程: 另一个例子是abcabcdabcabcdxyxyz可以被压缩为abcRdRMxyRz。
    Input

    输入仅一行,包含待压缩字符串,仅包含小写字母,长度为n。
    Output

    输出仅一行,即压缩后字符串的最短长度。
    Sample Input
    bcdcdcdcdxcdcdcdcd
    Sample Output
    12

    HINT

    在第一个例子中,解为aaaRa,在第二个例子中,解为bMcdRRxMcdRR。 【限制】 50%的数据满足:1<=n<=20 100%的数据满足:1<=n<=50 100%的数据满足:1<=n<=50

    区间dp

    f[l,r,k]表示区间[l,r]中间是否有M时的最短长度(一个是可能有,一个是一定没有,前面默认有一个M,合并的时候要记得补上)

     1 var
     2         flag:array[0..50,0..50,0..50,0..50]of boolean;
     3         f:array[0..50,0..50,0..1]of longint;
     4         n:longint;
     5         s:string;
     6  
     7 procedure init;
     8 var
     9         i,j,k:longint;
    10 begin
    11         readln(s);
    12         for i:=1 to length(s)-1 do
    13           for j:=i+1 to length(s) do
    14             if s[i]=s[j] then flag[i,i,j,j]:=true;
    15         for i:=1 to length(s)-1 do
    16           for j:=i+1 to length(s) do
    17             for k:=1 to length(s)-j do
    18               if flag[i,i+k-1,j,j+k-1] and (s[i+k]=s[j+k]) then flag[i,i+k,j,j+k]:=true;
    19 end;
    20  
    21 function min(x,y:longint):longint;
    22 begin
    23         if x<y then exit(x);
    24         exit(y);
    25 end;
    26  
    27 procedure dp;
    28 var
    29         i,j,k:longint;
    30 begin
    31         fillchar(f,sizeof(f),1);
    32         n:=length(s);
    33         for i:=1 to n do
    34           begin
    35             f[i,i,0]:=1;
    36             f[i,i,1]:=1;
    37           end;
    38         for k:=1 to n-1 do
    39           for i:=1 to n-k do
    40             begin
    41               if k and 1=1 then
    42               if flag[i,i+k>>1,i+k>>1+1,i+k] then
    43                 begin
    44                   f[i,i+k,1]:=f[i,i+k>>1,0]+1;
    45                   f[i,i+k,0]:=f[i,i+k,1];
    46                 end;
    47               for j:=i to i+k-1 do
    48                 begin
    49                   f[i,i+k,0]:=min(f[i,i+k,0],f[i,j,0]+i+k-j);
    50                   f[i,i+k,1]:=min(f[i,i+k,1],f[i,j,1]+f[j+1,i+k,1]+1);
    51                 end;
    52               f[i,i+k,1]:=min(f[i,i+k,0],f[i,i+k,1]);
    53             end;
    54         writeln(f[1,n,1]);
    55 end;
    56  
    57 begin
    58         init;
    59         dp;
    60 end.
    View Code
  • 相关阅读:
    js实现观察者模式
    磁盘阵列操作实战
    淘宝知名工程师
    Java线程并发控制基础知识
    java多线程总结
    NIO系列1:框架拆解
    Java NIO 系列教程
    Java NIO系列教程(三-十二) Buffer
    Java NIO系列教程(二) Channel
    Java NIO系列教程(一) Java NIO 概述
  • 原文地址:https://www.cnblogs.com/Randolph87/p/3681759.html
Copyright © 2011-2022 走看看