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

牛客刷题-Day12

牛客刷题-Day12

今日刷题:\(1056-1061\)

1057 [NOIP2001]统计单词个数

题目描述

给出一个长度不超过 \(200\) 的由小写英文字母组成的字母串(约定:该字串以每行 \(20\) 个字母的方式输入,且保证每行一定为 \(20\) 个)。要求将此字母串分成 \(k\) 份(\(1 < k ≤ 40\)),且每份中包含的单词个数加起来总数最大(每份中包含的单词可以部分重叠。当选用一个单词之后,其第一个字母不能再用。例如字符串 this 中可包含 thisis,选用 this 之后就不能包含 th)。
单词在给出的一个不超过 \(6\) 个单词的字典中。
要求输出最大的个数。

输入描述

每组的第一行有 \(2\) 个正整数 \(p,k\)
\(p\) 表示字串的行数,\(k\) 表示分为 \(k\) 个部分。
接下来的 \(p\) 行,每行均有 \(20\) 个字符。
再接下来有 \(1\) 个正整数 \(s\),表示字典中单词个数。(\(1 ≤ s ≤ 6\)
接下来的 \(s\) 行,每行均有 \(1\) 个单词。

输出描述

\(1\) 个整数,分别对应每组测试数据的相应结果。

示例

输入

1 3
thisisabookyouareaoh
4
is
a
ok
sab

输出

7

解题思路

参考:题解:P1026 [NOIP 2001 提高组] 统计单词个数

  • 状态表示:\(f_{i,j}\) 表示将前 \(j\) 个字符划分为 \(i\) 份的所含单词数,求解最大值。
  • 状态计算:枚举结尾,则 \(f_{i,j}=max\{f_{i,j},f_{i-1,t}+sum_{t+1,j}\}\),这里 \(i-1 \le t\le j-1\)\(sum_{i,j}\) 表示区间 \([i,j]\) 所含单词数的最大值。因为前面划分为 \(i\) 份至少含有 \(i\) 个字符串,而一个划分至少长度为 \(1\),由此得到 \(t\) 的取值范围。
  • \(sum_{i,j}\) 求解:因为选用一个单词,其所在首字母位置不能使用,因此如果 \(i\) 处开始无单词匹配,则 \(sum_{i,j}=sum_{i+1,j}\);否则 \(sum_{i,j}=sum_{i+1,j}+1\)

C++ 代码

#include <bits/stdc++.h>
using namespace std;
const int N = 210, M = 50;string str, s;
int p, k, n, m;
vector<string> dict;
int f[M][N]; // 分为 i 份且 j 为结尾所含单词数
int sum[N][N]; // [i, j] 包含单词数bool check(int a, int b) {int len = b - a + 1;int maxlen = 0;for (int i = 0; i < n; i++) maxlen = max(maxlen, (int) dict[i].size());if (len > maxlen)return false;for (int i = 0; i < n; i++) {if (len < dict[i].size())continue;if (str.substr(a, dict[i].size()) == dict[i])return true;}return false;
}void solve() {for (int l = m; l >= 1; l--) {if (check(l, l))sum[l][l] = 1;for (int r = l + 1; r <= m; r++) {sum[l][r] = sum[l + 1][r];for (int len = 2; l + len - 1 <= r; len++) {if (check(l, l + len - 1))sum[l][r] = max(sum[l][r], sum[l + 1][r] + 1);}}}for (int i = 1; i <= m; i++)f[1][i] = sum[1][i];for (int i = 2; i <= k; i++) // 划分数for (int j = i; j <= m; j++) // 结尾for (int t = i - 1; t < j; t++) // 枚举上一次划分的结尾f[i][j] = max(f[i][j], f[i - 1][t] + sum[t + 1][j]);cout << f[k][m];
}int main() {cin >> p >> k;str = "#";for (int i = 1; i <= p; i++) {cin >> s;str = str + s;}cin >> n;for (int i = 1; i <= n; i++) {cin >> s;dict.push_back(s);}m = str.size() - 1;solve();return 0;
}

1058 Min酱要旅行

题目描述

从前有个富帅叫做 \(Min\) 酱,他很喜欢出门旅行,每次出门旅行,他会准备很大一个包裹以及一大堆东西,然后尝试各种方案去塞满它。
然而每次出门前,\(Min\) 酱都会有个小小的烦恼。众所周知,富帅是很讨妹子喜欢的,所以 \(Min\) 酱也是有大把大把的妹子,每次出门都会有一只妹子随行。然而这些妹子总是会非常排斥 \(Min\) 酱准备的众多东西中的一件(也许是因为这件东西是其它妹子送给 \(Min\) 酱的),这件东西 \(Min\) 酱是万万不敢带上的,否则的话……嘿嘿嘿。另外,妹子们嫌 \(Min\) 酱的包裹太丑了,会自带一个包裹去换掉 \(Min\) 酱的包裹。
\(Min\) 酱是个控制欲很强的人,然而这样一来,\(Min\) 酱就不知道可以用多少种方案去填充包裹了,所以 \(Min\) 酱很郁闷。
于是 \(Min\) 酱找到了聪明的你,希望你能帮助他解决这些问题。
另外,\(Min\) 酱是个典型的懒人,他不希望每次带不同的妹子出去都麻烦你,所以他希望你能给出有 \(K_1,...,K_n\) 件物品,第 \(i\) 件不能带并且包裹大小为 \(1...M\) 的所有方案数。

输入描述

可能有多组数据。对于每一组数据:
第一行,两个整数 \(n,m\),分别表示物品数量和妹子带的包裹的最大容积。
第二行,\(n\) 个正整数,分别表示物品 \(K_i\) 的体积。

输出描述

对于每一组数据,输出一个 \(n×m\) 的矩阵,第 \(i\)\(j\) 列表示包裹容积为 \(j\),不能带 \(i\) 号物品时,装满包裹的方案总数。
为了美观起见,我们只保留方案数的个位。

示例

输入

3 2
1 1 2

输出

11
11
21

备注

\(1≤n,m≤2300,K_i ≤1000\)

解题思路

  • 状态表示:\(f_{i,j}\) 表示不选 \(i\) 且体积为 \(j\) 的方案数。
  • 状态计算:首先考虑正常的 \(01\) 背包问题,求解得到 \(dp_{i,j}\),表示前 i 个物品中选择且体积为 j 的方案数。如果当前体积小于 \(K_i\),则必然不会选择第 \(i\) 个物品,\(f_{i,j}=dp_{i,j}\);否则 \(f_{i,j}\) 需要在 \(dp_{i,j}\) 的基础上减去选择 \(i\) 且体积为 \(j\) 的方案数,即减去不选 \(i\) 体积为 \(j-K_i\)\(dp\) 方案数。

C++ 代码

#include <bits/stdc++.h>
using namespace std;
const int N = 2310;int n, m;
int a[N], dp[N], f[N]; // f[i][j] 表示不选 i 且体积为 j 的方案数int main() {scanf("%d%d", &n, &m);for (int i = 1; i <= n; i++)scanf("%d", &a[i]);// 纯 01 背包dp[0] = 1;for (int i = 1; i <= n; i++) {for (int j = m; j >= a[i]; j--)dp[j] = (dp[j] + dp[j - a[i]]) % 10;}for (int i = 1; i <= n; i++) {for (int j = 0; j <= m; j++) {if (j < a[i])f[j] = dp[j];elsef[j] = (dp[j] - f[j - a[i]] + 10) % 10;}for (int j = 1; j <= m; j++)printf("%d", f[j]);printf("\n");}return 0;
}

1060 [SCOI2009]粉刷匠

题目描述

\(windy\)\(N\) 条木板需要被粉刷。 每条木板被分为 \(M\) 个格子。 每个格子要被刷成红色或蓝色。
\(windy\) 每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色。 每个格子最多只能被粉刷一次。
如果 \(windy\) 只能粉刷 \(T\) 次,他最多能正确粉刷多少格子?
一个格子如果未被粉刷或者被粉刷错颜色,就算错误粉刷。

输入描述

输入文件 paint.in 第一行包含三个整数 \(N, M, T\)
接下来有 \(N\) 行,每行一个长度为 \(M\) 的字符串,0 表示红色,1 表示蓝色。

输出描述

输出文件 paint.out 包含一个整数,最多能正确粉刷的格子数。

示例1

输入

3 6 3
111111
000000
001100

输出

16

备注

\(30\%\) 的数据,满足 \(1≤N,M≤10\)\(0≤T≤100\)
\(100\%\) 的数据,满足 \(1≤N,M≤50\)\(0≤T≤2500\)

解题思路

参考:P4158 [SCOI2009]粉刷匠(分组背包问题+前缀和优化)

  • 状态表示:将每个木板当作一个背包组,粉刷次数为背包容量,粉刷正确的格子数为价值,\(f_{i,j}\) 表示前 \(i\) 个木板涂 \(j\) 次的价值,求解最大值。
  • 状态计算:\(f_{i,j}=max\{f_{i,j},f_{i-1,j-k}+g_{i,m,k}\}\)\(g_{i,j,k}\) 表示第 \(i\) 个木板的前 \(j\) 个格子涂 \(k\) 次的最大价值。那么需要先求解 \(g_{i,j,k}\)\(g_{i,j,k}=max\{g_{i,j,k-1},g_{i,q,k-1}+max\{sum0,sum1\}\}\),这里 \(sum\) 为第 \(i\) 个木板区间 \([q+1,j]\) 的红或者蓝格子数。

C++ 代码

#include <bits/stdc++.h>
using namespace std;
const int N = 55, M = 2510;int n, m, t; // n 看作背包组 t 看作背包容量 正确粉刷格子数为价值
char s[N][N];
int g[N][N][M]; // 第 i 条木板前 j 格子最多涂 k 次的价值
int f[N][M]; // 前 i 个木板涂 j 次的价值
int sum0[N][N], sum1[N][N];int main() {scanf("%d%d%d", &n, &m, &t);for (int i = 1; i <= n; i++) {scanf("%s", s[i] + 1);for (int j = 1; j <= m; j++) {if (s[i][j] == '1') {sum1[i][j] = sum1[i][j - 1] + 1;sum0[i][j] = sum0[i][j - 1];} else {sum0[i][j] = sum0[i][j - 1] + 1;sum1[i][j] = sum1[i][j - 1];}}}for (int i = 1; i <= n; i++)for (int j = 1; j <= m; j++)for (int k = 1; k <= m; k++) {g[i][j][k] = g[i][j][k - 1];for (int q = 0; q < j; q++) {int a = sum0[i][j] - sum0[i][q];int b = sum1[i][j] - sum1[i][q];g[i][j][k] = max(g[i][j][k], g[i][q][k - 1] + max(a, b));}}for (int i = 1; i <= n; i++)for (int j = 1; j <= t; j++)for (int k = 0; k <= min(j, m); k++) // 木板涂的次数不会超过其长度f[i][j] = max(f[i][j], f[i - 1][j - k] + g[i][m][k]);printf("%d\n", f[n][t]);return 0;
}
http://www.gsyq.cn/news/20004.html

相关文章:

  • 国产代码托管平台Gitee构建企业级安全防线 助力信创产业自主可控
  • AI重构项目管理:2025年工具生态的三大颠覆性趋势
  • 跨数据与任务的可扩展图像分割技术
  • 实用指南:大语言模型LLM解决AI幻觉方法的深度分析
  • ZKsync Baby Alpha里程碑达成:zkEVM技术架构全面解析
  • 深入解析:【MySQL✨】MySQL 入门之旅 第十一篇:常见错误排查与解决方案
  • 2025年10月家纺摄影公司最新推荐榜单,专业拍摄与创意设计一站式服务首选!
  • JAVA工具包
  • 2025年10月储罐源头厂家最新权威榜单:技术实力与市场口碑深度解析
  • 2025 年试验箱厂家最新推荐排行榜:聚焦高低温 / 恒温恒湿 / 冷热冲击等设备研发实力与 ISO 质量管控的标杆企业精选
  • 完整教程:PyTorch深度学习实战【12】之基于RNN的自然语言处理入门
  • 深入解析:用AI重塑电商,京东零售发布电商创新AI架构体系Oxygen
  • 2025 年最新推荐!防水堵漏工程公司权威榜单重磅发布,覆盖地下室 / 污水池 / 伸缩缝等场景,帮业主避开乱象选靠谱企业
  • 2025 药包材辅导公司最新推荐榜:含 GMP 验证 / 质量管理体系 / 实验室装修等服务优质机构盘点公司推荐
  • 2025年10月氢氧化镁厂家最新推荐排行榜,阻燃剂氢氧化镁,环保型氢氧化镁,高纯度氢氧化镁公司推荐!
  • 多进程环境中解决 PHP 文件系统锁定问题指南
  • mysql数据库定时执行sql语句
  • iSolarBP如何用技能重构全流程评估与设计?
  • 2025 年同声传译 APP 推荐!翻译鸥:AI 智能同传、视频 / 图片翻译工具,跨语言沟通实用之选
  • [数据模型/大数据] 数据建模之缓慢变化维
  • python第四天
  • Win10如何彻底关闭自动更新
  • 在AI技术唾手可得的时代,挖掘新需求成为核心竞争力——某知名媒体系统生态需求洞察
  • 20232403 2025-2026-1 《网络与系统攻防技术》实验一实验报告
  • 2025 年快速退火炉优质厂家最新推荐榜单:真空 / 半导体 / 晶圆 / 高温 / 桌面 / 半自动 / 全自动 / 芯片 / 硅片 / RTP 设备企业核心竞争力全面解析
  • 2025 年窗帘品牌最新推荐权威排行榜:精准剖析各品牌优势,定制 / 设计领先 / 家居等多类型窗帘优选母婴/遮光/智能/蕾丝/百叶/阳台/隔音/卷帘窗帘厂家推荐
  • 2025 年最新推荐!停车场系统厂商榜单重磅发布,涵盖管理 / 收费 / 无人值守 / 道闸 / 车牌识别系统优质服务商
  • oo
  • 实用指南:20250926的学习笔记
  • 2026 NOI 做题记录(六)