825F - String Compression

题意

给出一个字符串,你要把它尽量压缩成一个短的字符串,比如一个字符串ababab你可以转化成3ab,长度为 3,比如bbbacacb转化成3b2ac1b,长度为 7,aaaaaaaaaa转化为10a,长度为 3。

分析

求转换后的最短字符串,那么怎么去组合字符串中的子串是关键。

考虑 dp,dp[1...L] 对应字符串 S[0...L-1] 。dp[i] 表示字符串 S[0, i - 1] 转化后的字符串长度,dp[0] = 0。

状态转移方程:$ dp[i] = min(dp[i], dp[j] + has[j][i - 1]) $,其中 \(has[j][i - 1]\) 表示字符串 S[j, i - 1] 由某个字符(串)重复 k 次,k 取最大的时候,转化后的长度。比如ababab重复了两次,那么 \(has\) 的值为 3。

那么我们就要去预处理 has 的值,一个字符串(长度为 L)由 k 个连续且相同的子串组成,求 k 的最大值。这个问题不就是某个经典的字符串题吗?

当然不用后缀数组那么麻烦,那只是为了练习 : ) 。

考虑 KMP 算法中 nxt 数组的含义,对于字符串abcabc,那么 \(nxt[6] = 3\),即前缀后缀相同的子串长,我们称最小连续的那个子串为循环节,设 \(l = L - nxt[L]\),如果 \(l\) 刚好整除 \(L\),那么 \(l\) 就是循环节的长度。对于字符串ababab, \(nxt[6]=4\) ,假如后面还有字符,第 7 个字符导致失配,最后的四个字符abab不用再去匹配了,直接由abab向后匹配,正好是右移了一个循环节的位置。

code

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 8000 + 10;
const int INF = 1e9;
char T[MAXN];
int nxt[MAXN];
void getNext() {
int tlen = strlen(T);
int j, k;
j = 0;
k = -1;
nxt[0] = -1;
while(j < tlen)
if(k == -1 || T[j] == T[k])
nxt[++j] = ++k;
else
k = nxt[k];
}
int getl(int x) {
int cnt = 0;
while(x) {
cnt++;
x /= 10;
}
return cnt;
}
char S[MAXN];
int dp[MAXN];
int has[MAXN][MAXN];
int main() {
scanf("%s", S);
int L = strlen(S);
for(int i = 0; i < L; i++) {
has[i][i] = 2;
int l = 0;
for(int j = i; j < L; j++) {
T[l++] = S[j];
}
T[l] = 0;
getNext();
l = 0;
for(int j = i + 1; j < L; j++) {
l++;
int k = j - i + 1;
int p = k - nxt[l + 1];
if(k % p == 0) {
has[i][j] = getl(k / p) + p;
} else has[i][j] = j - i + 2;
}
}
dp[0] = 0; // dp[1..L] 对应字符串 S[0..L-1]
for(int i = 1; i <= L; i++) {
dp[i] = i + 1;
for(int j = 0; j < i; j++) {
// [j + 1, i] 对应字符串的 [j, i - 1]
dp[i] = min(dp[i], dp[j] + has[j][i - 1]);
}
}
printf("%d\n", dp[L]);
return 0;
}

Codeforces 825F - String Compression的更多相关文章

  1. Codeforces 852F String Compression

    题目 OvO http://codeforces.com/contest/825/problem/F 题解 KMP+DP 十分优雅地利用了KMP的fail数组 fail[k]表示第k个后缀的的fail ...

  2. codeforces 825F F. String Compression dp+kmp找字符串的最小循环节

    /** 题目:F. String Compression 链接:http://codeforces.com/problemset/problem/825/F 题意:压缩字符串后求最小长度. 思路: d ...

  3. UVA 1351 十三 String Compression

    String Compression Time Limit:3000MS     Memory Limit:0KB     64bit IO Format:%lld & %llu Submit ...

  4. 【leetcode】443. String Compression

    problem 443. String Compression Input ["a","a","b","b"," ...

  5. 443. String Compression

    原题: 443. String Compression 解题: 看到题目就想到用map计数,然后将计数的位数计算处理,这里的解法并不满足题目的额外O(1)的要求,并且只是返回了结果array的长度,并 ...

  6. CF825F String Compression 解题报告

    CF825F String Compression 题意 给定一个串s,其中重复出现的子串可以压缩成 "数字+重复的子串" 的形式,数字算长度. 只重复一次的串也要压. 求压缩后的 ...

  7. 213. String Compression【LintCode java】

    Description Implement a method to perform basic string compression using the counts of repeated char ...

  8. 213. String Compression【easy】

    Implement a method to perform basic string compression using the counts of repeated characters. For ...

  9. 区间DP UVA 1351 String Compression

    题目传送门 /* 题意:给一个字符串,连续相同的段落可以合并,gogogo->3(go),问最小表示的长度 区间DP:dp[i][j]表示[i,j]的区间最小表示长度,那么dp[i][j] = ...

随机推荐

  1. leetcode 【 Linked List Cycle 】 python 实现

    题目: Given a linked list, determine if it has a cycle in it. Follow up:Can you solve it without using ...

  2. oschina添加ssh公钥一记

    生成SSH公钥 --------------------------------------------------------- 打开Windows Shell 或 GIT Bash ssh-key ...

  3. flask利用session身份伪造

    想研究很久了,这次终于初步了解了flask session伪造(得知道密钥). python2和python3 session解密不一样,而且不都是base64,脚本https://github.co ...

  4. PAT——甲级1042:Shuffling Mashine

    终于做到甲级了 就一个感觉....题目是真的看不懂,亏我还是四六级都过了的人....可是看完题愣是一点都不懂是什么意思. 1042 Shuffling Machine (20 point(s)) Sh ...

  5. shell之基本语法

    转:   read 命令从 stdin 获取输入并赋值给 PERSON 变量,最后在 stdout 上输出: #!/bin/bash # Script follows here: echo " ...

  6. shell之一些测试脚本

    比较文件有无修改,通过修改时间判别 # !/bin/bash dir=$ for file in `ls $dir` do if [ -d $dir/$file ] then echo $file i ...

  7. webpack 基础

    1.安装: npm install --save-dev webpack         npm install --save-dev webpack@<version> 如果是webpa ...

  8. A - 最长上升子序列

    A - 最长上升子序列 Time Limit: 1000/1000MS (C++/Others) Memory Limit: 65536/65536KB (C++/Others) Problem De ...

  9. (总结)统计Apache或Nginx访问日志里的独立IP访问数量的Shell

    1.把IP数量直接输出显示:cat access_log_2011_06_26.log |awk '{print $1}'|uniq -c|wc -l 2.把IP数量输出到文本显示:cat acces ...

  10. BZOJ 1861: [Zjoi2006]Book 书架 | SPlay 板题

    #include<cstdio> #include<algorithm> #include<cstring> #define N 80010 #define whi ...