当前位置: 首页 > news >正文

UVa 1630 Folding

题目分析

本题要求我们将一个由大写字母组成的字符串压缩成最短的形式,压缩规则是使用 数字(重复子串) 的格式表示重复部分。

压缩规则

  • 单个字符保持原样
  • 如果 SSSQQQ 是压缩后的字符串,那么 SQSQSQ 也是压缩后的字符串
  • 如果 SSS 是压缩后的字符串,那么 X(S)X(S)X(S) 也是压缩后的字符串,其中 XXX 是大于 111 的整数,表示 SSS 重复 XXX

问题示例

输入字符串 AAAAAAAAABABABCCD 可以压缩为 9(A)3(AB)CCD

问题本质

这是一个区间动态规划问题,我们需要找到字符串的最优折叠方式,使得压缩后的字符串长度最短。

解题思路

动态规划定义

dp[i][j]dp[i][j]dp[i][j] 表示子串 s[i..j]s[i..j]s[i..j] 的最短压缩字符串表示。

状态初始化

  • 对于长度为 111 的子串,dp[i][i]=s[i]dp[i][i] = s[i]dp[i][i]=s[i](即单个字符本身)

状态转移

对于每个子串 s[i..j]s[i..j]s[i..j],我们考虑两种压缩方式:

  1. 分割压缩:将子串分成两部分 s[i..k]s[i..k]s[i..k]s[k+1..j]s[k+1..j]s[k+1..j],分别压缩后再拼接:
    dp[i][j]=min⁡(dp[i][j],dp[i][k]+dp[k+1][j])dp[i][j] = \min(dp[i][j], dp[i][k] + dp[k+1][j]) dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j])
    其中 i≤k<ji \leq k < jik<j

  2. 重复模式压缩:如果整个子串可以由一个更短的子串重复多次构成,则使用 X(S)X(S)X(S) 的形式:
    dp[i][j]=min⁡(dp[i][j],to_string(times)+‘(’+dp[i][i+l−1]+‘)’)dp[i][j] = \min(dp[i][j], \text{to\_string}(times) + ‘(’ + dp[i][i+l-1] + ‘)’ ) dp[i][j]=min(dp[i][j],to_string(times)+(+dp[i][i+l1]+))
    其中 lll 是重复单元的长度,times=lenltimes = \frac{len}{l}times=llen 是重复次数

重复模式检查

对于子串 s[i..j]s[i..j]s[i..j],长度为 len=j−i+1len = j-i+1len=ji+1,我们检查所有可能的重复单元长度 lll1≤l<len1 \leq l < len1l<len):

  • 必须满足 len%l==0len \% l == 0len%l==0
  • 必须满足 s[i..j]s[i..j]s[i..j] 是由 s[i..i+l−1]s[i..i+l-1]s[i..i+l1] 重复 times=len/ltimes = len/ltimes=len/l 次构成

算法复杂度

  • 时间复杂度:O(n3)O(n^3)O(n3),其中 n≤100n \leq 100n100,完全可行
  • 空间复杂度:O(n2)O(n^2)O(n2)

代码实现

// Folding
// UVa ID: 1630
// Verdict: Accepted
// Submission Date: 2025-10-19
// UVa Run Time: 0.110s
//
// 版权所有(C)2025,邱秋。metaphysis # yeah dot net#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;string fold(const string& s) {int n = s.size();vector<vector<string>> dp(n, vector<string>(n));// 初始化:长度为1的子串for (int i = 0; i < n; i++) dp[i][i] = s[i];// 枚举所有子串长度for (int len = 2; len <= n; len++) {for (int i = 0; i + len - 1 < n; i++) {int j = i + len - 1;// 初始化为原子串dp[i][j] = s.substr(i, len);// 1. 尝试分割点for (int k = i; k < j; k++) {string candidate = dp[i][k] + dp[k + 1][j];if (candidate.size() < dp[i][j].size()) dp[i][j] = candidate;}// 2. 尝试重复模式for (int l = 1; l < len; l++) {if (len % l == 0) {bool repeatOk = true;// 检查是否满足重复条件for (int pos = i; pos <= j; pos++) {if (s[pos] != s[i + (pos - i) % l]) {repeatOk = false;break;}}if (repeatOk) {int times = len / l;string candidate = to_string(times) + "(" + dp[i][i + l - 1] + ")";if (candidate.size() < dp[i][j].size()) dp[i][j] = candidate;}}}}}return dp[0][n - 1];
}int main() {string line;while (getline(cin, line)) {if (line.empty()) continue;cout << fold(line) << '\n';}return 0;
}

代码说明

  1. 数据结构:使用二维向量 dp 存储所有子串的最优压缩结果
  2. 初始化:单个字符的压缩结果就是字符本身
  3. 动态规划填充:按子串长度从小到大计算,确保子问题先被解决
  4. 两种压缩策略
    • 分割策略:枚举所有可能的分割点
    • 重复模式:检查所有可能的重复单元长度
  5. 最优选择:总是选择长度最短的压缩表示

总结

本题通过区间动态规划的方法,系统地考虑了字符串的所有可能压缩方式,确保了找到最优解。关键点在于正确处理两种压缩策略:分割拼接和重复模式,其中重复模式的检查是算法的核心难点。

http://www.dtcms.com/a/503733.html

相关文章:

  • 基于AT89C52的智能温控风扇设计
  • 32HAL——IIC温度传感器AHT20
  • 站群wordpress宣武深圳网站建设公司
  • 构建自主AI的挑战与对策:稳定性、成本与伦理安全
  • 汽车服务站建站流程网页网站原型图占位符怎么做
  • 高效解决重装后常见的7类系统适配问题
  • 如何写好代码
  • PS2020使用教程|绘制文明行车宣传画
  • 探索 C++ 类 核心概念与不同场景下的使用技巧
  • 权威机构统计的 AI 编程模型排名
  • 佛山网站建设与推广学院网站群建设方案
  • 【HTTP知识】HTTP OPTIONS 预检请求深度解析与优化策略
  • 网站建设推广好处响应式网站开发报价
  • 汽车MIMO雷达在多径环境下的角度估计——论文阅读
  • 做网站的实践报告包头网站建设良居网络
  • 【论文精度-3】POMO:强化学习中具有多个最优解的策略优化方法(Yeong-Dae Kwon 2020)
  • 基本控件-上(Num30)
  • FFmpeg 基本API avcodec_find_decoder函数内部调用流程分析
  • 用wordpress建立学校网站吗淄博公司网站建设效果
  • C++ std::Set<std::pair>
  • 如何解决 pip install -r requirements.txt 私有仓库认证失败 401 Unauthorized 问题
  • LLMs-from-scratch(第3章:编码注意力机制)
  • 江西赣建建设监理网站无锡市建设工程质量监督站网站
  • 如何生成逼真的合成表格数据:独立采样与关联建模方法对比
  • FastGPT 与 MCP 协议概述
  • 软路由系统如何做网站上海做网站seo
  • K8S--ConfigMap的用法
  • Docker 常用命令整理
  • 网站降权原因北京公司车牌指标
  • 【片上网络专题讨论一】 片上总线的发展历程