牛客题解 | [CQOI2007]涂色PAINT
1.牛客题解 | N皇后问题
2.牛客题解 | [CQOI2007]涂色PAINT
3.牛客题解 | [NOIP2001]装箱问题4.牛客题解 | [NOIP2002 普及组] 过河卒5.牛客题解 | [ZJOI2010]COUNT 数字计数6.牛客题解 | abb7.牛客题解 | ranko的手表8.牛客题解 | 【模板】01背包9.牛客题解 | 【模板】二维前缀和10.牛客题解 | 【模板】二维差分11.牛客题解 | 【模板】前缀和12.牛客题解 | 【模板】单源最短路113.牛客题解 | 【模板】哈夫曼编码14.牛客题解 | 【模板】完全背包15.牛客题解 | 【模板】差分16.牛客题解 | 【模板】循环队列17.牛客题解 | 【模板】链表18.牛客题解 | 三角形最小路径和19.牛客题解 | 不相邻取数20.牛客题解 | 串21.牛客题解 | 乘积为正数的最长连续子数组22.牛客题解 | 买卖股票的最好时机(一)23.牛客题解 | 买卖股票的最好时机(三)24.牛客题解 | 买卖股票的最好时机(二)25.牛客题解 | 买卖股票的最好时机(四)26.牛客题解 | 二分查找-I27.牛客题解 | 二叉树中的最大路径和28.牛客题解 | 从中序与后序遍历序列构造二叉树29.牛客题解 | 信封嵌套30.牛客题解 | 兑换零钱31.牛客题解 | 分割等和子集32.牛客题解 | 删除相邻数字的最大分数33.牛客题解 | 删除链表的节点34.牛客题解 | 反转链表题目
解题思路
-
状态定义:
- 表示区间 染色需要的最少次数
-
转移方程:
- 当 时:
- 当 时:
-
实现要点:
- 字符串下标从 开始,方便处理
- 初始化 数组为较大值
- 长度为 的区间初始化为
代码
#include <bits/stdc++.h>
using namespace std;
int dp[51][51];
int main() {
string s;
cin >> s;
int n = s.size();
// 将字符串下标从1开始
s = " " + s;
// 初始化dp数组为较大值
memset(dp, 0x3f, sizeof dp);
// 初始化长度为1的区间
for(int i = 1; i <= n; i++) {
dp[i][i] = 1;
}
// 枚举区间长度
for(int len = 2; len <= n; len++) {
// 枚举左端点
for(int i = 1; i + len - 1 <= n; i++) {
int j = i + len - 1; // 右端点
// 如果区间两端颜色相同
if(s[i] == s[j]) {
dp[i][j] = min(dp[i+1][j], dp[i][j-1]);
} else {
// 枚举分割点
for(int k = i; k < j; k++) {
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k+1][j]);
}
}
}
}
cout << dp[1][n];
return 0;
}
import java.util.Scanner;
import java.util.Arrays;
public class Main {
static int[][] dp = new int[51][51];
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String s = sc.next();
int n = s.length();
// 将字符串下标从1开始
s = " " + s;
// 初始化dp数组为较大值
for(int[] row : dp) {
Arrays.fill(row, 0x3f3f3f3f);
}
// 初始化长度为1的区间
for(int i = 1; i <= n; i++) {
dp[i][i] = 1;
}
// 枚举区间长度
for(int len = 2; len <= n; len++) {
// 枚举左端点
for(int i = 1; i + len - 1 <= n; i++) {
int j = i + len - 1; // 右端点
// 如果区间两端颜色相同
if(s.charAt(i) == s.charAt(j)) {
dp[i][j] = Math.min(dp[i+1][j], dp[i][j-1]);
} else {
// 枚举分割点
for(int k = i; k < j; k++) {
dp[i][j] = Math.min(dp[i][j], dp[i][k] + dp[k+1][j]);
}
}
}
}
System.out.println(dp[1][n]);
sc.close();
}
}
def solve(s: str) -> int:
n = len(s)
# 将字符串下标从1开始
s = " " + s
# 初始化dp数组
dp = [[float('inf')] * (n + 1) for _ in range(n + 1)]
# 初始化长度为1的区间
for i in range(1, n + 1):
dp[i][i] = 1
# 枚举区间长度
for length in range(2, n + 1):
# 枚举左端点
for i in range(1, n - length + 2):
j = i + length - 1 # 右端点
# 如果区间两端颜色相同
if s[i] == s[j]:
dp[i][j] = min(dp[i+1][j], dp[i][j-1])
else:
# 枚举分割点
for k in range(i, j):
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k+1][j])
return dp[1][n]
def main():
s = input().strip()
print(solve(s))
if __name__ == "__main__":
main()
算法及复杂度
- 算法:区间动态规划
- 时间复杂度:,其中 是字符串长度
- 空间复杂度:,用于存储 数组
合集:
牛客笔试必刷101题单题解
分类:
牛客笔试必刷101题单题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!