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

信奥赛CSP-J复赛集训(DP专题)(37):P4170 [CQOI2007] 涂色

信奥赛CSP-J复赛集训(DP专题)(37):P4170 [CQOI2007] 涂色

在这里插入图片描述

题目描述

假设你有一条长度为 5 5 5 的木板,初始时没有涂过任何颜色。你希望把它的 5 5 5 个单位长度分别涂上红、绿、蓝、绿、红色,用一个长度为 5 5 5 的字符串表示这个目标: RGBGR \texttt{RGBGR} RGBGR

每次你可以把一段连续的木板涂成一个给定的颜色,后涂的颜色覆盖先涂的颜色。例如第一次把木板涂成 RRRRR \texttt{RRRRR} RRRRR,第二次涂成 RGGGR \texttt{RGGGR} RGGGR,第三次涂成 RGBGR \texttt{RGBGR} RGBGR,达到目标。

用尽量少的涂色次数达到目标。

输入格式

输入仅一行,包含一个长度为 n n n 的字符串,即涂色目标。字符串中的每个字符都是一个大写字母,不同的字母代表不同颜色,相同的字母代表相同颜色。

输出格式

仅一行,包含一个数,即最少的涂色次数。

输入输出样例 #1

输入 #1

AAAAA

输出 #1

1

输入输出样例 #2

输入 #2

RGBGR

输出 #2

3

说明/提示

40 % 40\% 40% 的数据满足 1 ≤ n ≤ 10 1\le n\le 10 1n10

100 % 100\% 100% 的数据满足 1 ≤ n ≤ 50 1\le n\le 50 1n50

AC代码:

#include<bits/stdc++.h>
using namespace std;char s[60]; // 存储输入的字符串
int dp[60][60]; // dp[l][r]表示将区间[l..r]涂成目标颜色所需的最少次数int main(){scanf("%s", s + 1); // 从s[1]开始读取字符串int n = strlen(s + 1); // 获取字符串长度memset(dp, 0x3f, sizeof(dp)); // 初始化为极大值,表示不可达// 初始化单个字符的情况for(int i = 1; i <= n; i++){dp[i][i] = 1; // 单个字符只需涂一次}// 动态规划处理所有区间for(int k = 2; k <= n; k++){ // 枚举区间长度,从2到nfor(int l = 1; l + k - 1 <= n; l++){ // 枚举区间左端点lint r = l + k - 1; // 计算区间右端点r// 如果区间两端字符相同,则可能合并涂色if(s[l] == s[r]){dp[l][r] = min(dp[l + 1][r], dp[l][r - 1]); // 取不包含左端点或不包含右端点的子区间的最小值}// 遍历所有可能的分割点,寻找更优解for(int i = l; i < r; i++){dp[l][r] = min(dp[l][r], dp[l][i] + dp[i + 1][r]);}}}printf("%d\n", dp[1][n]); // 输出整个字符串的最少涂色次数return 0;
}

功能分析:

该程序采用动态规划解决区间涂色问题,关键点如下:

  1. 状态定义dp[l][r]表示将区间[l..r]涂成目标颜色所需的最少次数。

  2. 初始化:每个单字符区间dp[i][i]初始化为1,因为只需一次涂色。

  3. 状态转移

    • 两端相同处理:若区间两端字符相同,则dp[l][r]可取左右子区间的最小值,因为可以在涂色时覆盖端点。
    • 分割点遍历:枚举所有可能的分割点i,将区间分为[l..i][i+1..r],取两部分次数和的最小值。
  4. 自底向上计算:从小区间逐步求解大区间,确保每个区间的解都基于最优子结构。

  5. 复杂度:时间复杂度为O(n³),适用于题目中的n≤50的数据范围。

文末彩蛋:

关注并查看老师的个人主页,学习完整csp信奥赛完整系列课程: https://edu.csdn.net/lecturer/7901

在这里插入图片描述

http://www.xdnf.cn/news/4281.html

相关文章:

  • [学习]RTKLib详解:rtkcmn.c与rtkpos.c
  • 学习Python的第二天之网络爬虫
  • cephadm部署ceph集群
  • php案列
  • QML ProgressBar控件详解
  • G919-GAS软件 JSON格式数据通讯协议-阵列数据解析
  • SQLark可以支持PostgreSQL了,有哪些新功能?
  • C++ Avl_Tree
  • 239. 滑动窗口最大值
  • yolo训练用的数据集的数据结构
  • RPA自动化:开启智能流程新时代
  • OpenCV 图形API(77)图像与通道拼接函数-----对图像进行几何变换函数remap()
  • 面试常问系列(一)-神经网络参数初始化-之-softmax
  • java springboot解析出一个图片的多个二维码
  • 软考-软件设计师中级备考 13、刷题 数据结构
  • k8s node soft lockup (内核软死锁) 优化方案
  • python3使用:macOS上通过Homebrew安装pip库
  • linux 如何防止内存碎片化?
  • C#中不能通过new关键字创建实例的情况
  • conda虚拟环境相关操作
  • LeetCode 热题 100 39. 组合总和
  • Jetpack Compose 自定义 Slider 完全指南
  • QT键盘触发按钮
  • laravel 12 监听syslog消息,并将消息格式化后存入mongodb
  • 深度解析:2D 写实交互数字人 —— 开启智能交互新时代
  • API 开发实战:基于京东开放平台的实时商品数据采集接口实现
  • 【25软考网工】第五章(6)TCP和UDP协议、流量控制和拥塞控制、重点协议与端口
  • 项目中为什么选择RabbitMQ
  • Vision-Language Models (VLMs) 视觉语言模型的技术背景、应用场景和商业前景(Grok3 DeepSearch模式回答)
  • 隔离端口配置