【Codeforces】CF 2005 C

news2024/10/10 9:15:07

Lazy Narek

#动态规划 #字符串 #贪心

题目描述

Narek is too lazy to create the third problem of this contest. His friend Artur suggests that he should use ChatGPT. ChatGPT creates n n n problems, each consisting of m m m letters, so Narek has n n n strings. To make the problem harder, he combines the problems by selecting some of the n n n strings possibly none and concatenating them without altering their order. His chance of solving the problem is defined as s c o r e n − s c o r e c score_n - score_c scorenscorec, where s c o r e n score_n scoren is Narek’s score and s c o r e c score_c scorec is ChatGPT’s score.

Narek calculates s c o r e n score_n scoren by examining the selected string (he moves from left to right). He initially searches for the letter "n" \texttt{"n"} "n", followed by "a" \texttt{"a"} "a", "r" \texttt{"r"} "r", "e" \texttt{"e"} "e", and "k" \texttt{"k"} "k". Upon finding all occurrences of these letters, he increments s c o r e n score_n scoren by 5 5 5 and resumes searching for "n" \texttt{"n"} "n" again (he doesn’t go back, and he just continues from where he left off).

After Narek finishes, ChatGPT scans through the array and increments s c o r e c score_c scorec by 1 1 1 for each letter "n" \texttt{"n"} "n", "a" \texttt{"a"} "a", "r" \texttt{"r"} "r", "e" \texttt{"e"} "e", or "k" \texttt{"k"} "k" that Narek fails to utilize (note that if Narek fails to complete the last occurrence by finding all of the 5 5 5 letters, then all of the letters he used are counted in ChatGPT’s score s c o r e c score_c scorec, and Narek doesn’t get any points if he doesn’t finish finding all the 5 letters).

Narek aims to maximize the value of s c o r e n − s c o r e c score_n - score_c scorenscorec by selecting the most optimal subset of the initial strings.

输入格式

In the first line of the input, you’re given a single integer t t t ( 1 ≤ t ≤ 1 0 5 1 \le t \le 10^5 1t105), the number of test cases. Then the description of each test case follows.

In the first line of each test case, you’re given two integers n , m n, m n,m ( 1 ≤ n , m ≤ 1 0 3 1 \le n, m \le 10^3 1n,m103), the number of strings and the length of each string.

In the next n n n lines, you’re given n n n strings, each having a length of m m m. The strings only contain lowercase letters of the English alphabet.

The sum of values of n ⋅ m n \cdot m nm over all test cases does not exceed 1 0 6 10^6 106.

输出格式

For each test case, output a single integer: the maximal possible value of s c o r e n − s c o r e c score_n - score_c scorenscorec.

样例 #1

样例输入 #1

4
5 2
nn
aa
rr
ee
kk
1 5
narek
1 4
nare
5 7
nrrarek
nrnekan
uuuuuuu
ppppppp
nkarekz

样例输出 #1

0
5
0
7

解法

解题思路

首先每个字符串都有选择和不选择的两种方式,但是,如果选择了这个字符串,那么一定会选择它的所有匹配的子串。 因此,对于前者,我们使用动态规划,而对于动态规划中的子问题,则是直接使用贪心来匹配子串。

因为每次匹配,最后可能会以 [ n , a , r , e , k ] [n,a,r,e,k] [n,a,r,e,k]中其中一个结尾,因此设计动态规划状态为 f i , j f_{i,j} fi,j,表示选择第 i i i个字符串的时候,以 n a r e k narek narek的第 j j j个字符结束。

注意这里的 j = { 0 , 1 , 2 , 3 , 4 } j = \{0,1,2,3,4\} j={0,1,2,3,4}分别对应以 { k , n , a , r , e } \{k,n,a,r,e\} {k,n,a,r,e}结尾。

那么显然有以下的转移:
{ f i , j = max ⁡ ( f i , j , f i − 1 , j )    j ∈ { 0 , 1 , 2 , 3 , 4 } f i , k = max ⁡ ( f i , k , f i − 1 , j   + s u m j k )    j , k ∈ { 0 , 1 , 2 , 3 , 4 } \begin{cases} f_{i,j} = \max(f_{i,j},f_{i-1,j} ) \ \ j \in\{0,1,2,3,4\} \\ f_{i,k} = \max(f_{i,k},f_{i-1,j} \ +sum_j^k ) \ \ j,k \in \{0,1,2,3,4\} \end{cases} {fi,j=max(fi,j,fi1,j)  j{0,1,2,3,4}fi,k=max(fi,k,fi1,j +sumjk)  j,k{0,1,2,3,4}

其中 s u m j k sum_j^k sumjk表示贪心地从 j j j结尾的字符开始选,选到 k k k结尾的字符获得的贡献。

最后,我们计算答案的时候,要减去不完整的部分的贡献,比如我们选择答案以 j = 3 j=3 j=3,即 r r r结尾,那么答案贡献需要减去 3 3 3,因为要丢掉 r e k rek rek这三个贡献,并且加到 G P T GPT GPT上。

所以答案为 max ⁡ j = 0 j ≤ 4 ( f n , j − j ) \max_{j=0}^{j \leq4}(f_{n,j} - j) maxj=0j4(fn,jj)

代码


const int N = 1e3 + 10;
 
int f[N][5];
std::string t = "narek";
void solve() {
	int n, m;
	std::cin >> n >> m;
 
	std::vector<std::string>a(n + 1);
	for (int i = 1; i <= n; ++i) {
		std::cin >> a[i];
	}
 
	memset(f, -0x3f, sizeof(f));
 
	f[0][0] = 0;
	for (int i = 1; i <= n; ++i) {
		for (int j = 0; j < 5; ++j) {
			int k = j, res = f[i - 1][j];
			for (auto& c : a[i]) {
				if (c == t[k]) {
					++k;
					if (k == 5) {
						res += 5;
						k = 0;
					}
				}
				else if (t.find(c) != std::string::npos) {
					--res;
				}
			}
			f[i][k] = std::max(f[i][k], res);
		}
		for (int j = 0; j < 5; ++j) {
			f[i][j] = std::max(f[i][j], f[i - 1][j]);
		}
	}
 
 
	int res = 0;
	for (int i = 0; i < 5; i++) {
		res = std::max(res, f[n][i] - i);
	}
	std::cout << res << "\n";
 
}
 
signed main() {
	std::ios::sync_with_stdio(0);
	std::cin.tie(0);
	std::cout.tie(0);
 
	int t = 1;
	std::cin >> t;
 
	while (t--) {
		solve();
	}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2201621.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python酷库之旅-第三方库Pandas(140)

目录 一、用法精讲 631、pandas.Timestamp类 631-1、语法 631-2、参数 631-3、功能 631-4、返回值 631-5、说明 631-6、用法 631-6-1、数据准备 631-6-2、代码示例 631-6-3、结果输出 632、pandas.Timestamp.asm8属性 632-1、语法 632-2、参数 632-3、功能 632…

java类和对象_成员变量方法修饰符局部变量this关键字-cnblog

java类和对象 成员变量 权限修饰符 变量类型 变量名; 成员变量可以是任意类型,整个类是成员变量的作用范围 成员变量 成员方法 权限修饰符 返回值类型 方法名() 成员方法可以有参数&#xff0c;也可以有返回值&#xff0c;用return声明 权限修饰符 private 只能在本类…

IDEA必装的插件:Spring Boot Helper的使用与功能特点

在IntelliJ IDEA中&#xff0c;Spring Boot Helper插件是一个非常实用的工具&#xff0c;可以帮助我们更快速地创建和管理Spring Boot项目。以下是Spring Boot Helper插件的详细介绍和使用方法&#xff1a; 激活码地址: 点击获取 一、安装Spring Boot Helper插件 1 打开Intell…

如何设计三极管放大电路?

设计放大电路 分压式串联负反馈放大电路 可以看下面这个视频 , 讲得更加详细 366-单管放大电路偏置电阻的计算&#xff0c;看完自己也会设计一个_哔哩哔哩_bilibili 计算流过电阻Rb2的电流过程中,工程当中常发现Rb2上的电流是Ib的5倍 , 因此由基尔霍夫电流定律也能知道流过R…

Java的基础概念和常识(二)

什么是字节码&#xff1f;采用字节码的好处是什么&#xff1f; 字节码&#xff08;Byte-code&#xff09;是一种中间形式的代码&#xff0c;是源代码编译后生成的一种低级表示&#xff0c;通常是在编译阶段生成的。在 Java 中&#xff0c;JVM 可以理解的代码就叫做字节码&…

K8s(学习笔记)

swap分区是什么呀&#xff1f; 什么是ipvs呀&#xff1f; yaml是什么呀&#xff1f;&#xff1f;&#xff1f; p20看不下去了&#xff01;&#xff01;&#xff01;

ansible 流程控制

目录 1.流程控制 2.handlers触发器 2.1使用handlers案例 3.when 判断 3.1 案例1 用于给task设置条件 满足或者不满足运行对应模块 3.2 案例2 如果系统是centos则安装sl&#xff0c;cowsay 如果是unbantu则安装cmatrix 4.循环 4.1案例 1.流程控制 hand…

飞腾CPU技术发展分析

飞腾CPU剖析 CPU&#xff1a;信创根基&#xff0c;国之重器 国产CPU市场呈现三大领军阵营&#xff1a;x86、ARM以及其他创新架构。鲲鹏与飞腾在ARM阵营中引领风潮&#xff0c;依托ARM技术授权研发高性能处理器&#xff1b;海光与兆芯则以x86架构为基石&#xff0c;深入挖掘其潜…

图论day56|广度优先搜索理论基础 、bfs与dfs的对比(思维导图)、 99.岛屿数量(卡码网)、100.岛屿的最大面积(卡码网)

图论day56|广度优先搜索理论基础 、bfs与dfs的对比&#xff08;思维导图&#xff09;、 99.岛屿数量&#xff08;卡码网&#xff09;、100.岛屿的最大面积&#xff08;卡码网&#xff09;&#xff09; 广度优先搜索理论基础bfs与dfs的对比&#xff08;思维导图&#xff09;&…

Spring Boot Starter Parent介绍

引言 spring-boot-starter-parent 是一个特殊的项目&#xff0c;为基于 Spring Boot 的应用程序提供默认配置和默认依赖。 在本 Spring Boot 教程中&#xff0c;我们将深入了解所有 Spring Boot 项目内部使用的 spring-boot-starter-parent 依赖项。我们将探讨此依赖项所提供…

基于jmeter+perfmon的稳定性测试记录

1. 引子 最近承接了项目中一些性能测试的任务&#xff0c;因此决定记录一下&#xff0c;将测试的过程和一些心得收录下来。 说起来性能测试算是软件测试行业内&#xff0c;有些特殊的部分。这部分的测试活动&#xff0c;与传统的测试任务差别是比较大的&#xff0c;也比较依赖…

用Python实现运筹学——Day 12: 线性规划在物流优化中的应用

一、学习内容 线性规划在物流优化中可以用于解决诸如配送路径优化、货物运输调度等问题。配送中心的路径优化问题本质上是寻找一条最优路径&#xff0c;在满足需求点的需求条件下&#xff0c;最小化配送的总运输成本或时间。常见的物流优化问题包括&#xff1a; 配送中心的货…

集师知识付费小程序:打造培训机构在线教育的金字招牌 集师知识付费系统 集师知识付费小程序 集师知识服务系统 集师线上培训系统 集师线上卖课小程序

在数字化浪潮的推动下&#xff0c;在线教育已成为教育领域的热门话题。而在众多在线教育平台中&#xff0c;集师知识付费小程序凭借其独特的定位和创新的模式&#xff0c;成功为培训机构打造了一张闪亮的在线教育金字招牌。 集师知识付费小程序&#xff0c;是一个集课程展示、…

Python 如何使用 Matplotlib 和 Seaborn 可视化数据

Python 如何使用 Matplotlib 和 Seaborn 可视化数据 一、简介 数据可视化是数据分析过程中非常重要的步骤。通过可视化&#xff0c;复杂的数据变得更直观&#xff0c;数据中的模式、趋势和异常可以更容易被识别。Python 提供了多个强大的库来进行数据可视化&#xff0c;其中最…

ChatGPT:引领人工智能新潮流!

一、ChatGPT 是什么&#xff1f; 1. ChatGPT 的强大功能和广泛应用。 ChatGPT 作为一款先进的 AI 语言模型&#xff0c;拥有众多强大功能。它可以进行文本生成、文本分类、情感分析、机器翻译等多种自然语言处理任务。同时&#xff0c;ChatGPT 还能进行对话式交互&#xff0c;…

python之详解集合

一种无序且不重复的数据容器&#xff0c;集合用大括号{}表示。 1、集合的查找访问 集合是不能通过 集合名[index] 这种方式访问的&#xff0c;其作用在于快速读取&#xff0c;而不是针对某个元素。 但&#xff0c;可将集合转为列表&#xff0c;再由列表访问元素。不过&#…

Laravel Filament 如何配置多语言支持

演示 一、安装拓展包outerweb/filament-translatable-fields composer require outerweb/filament-translatable-fields配置模型 该套件包含一个名为 HasTranslations 的特性&#xff0c;用于使 Eloquent 模型具备多语言功能。翻译值以 JSON 格式存储&#xff0c;并不需要额外…

叙说 OSI 七层网络模型 | 你在第几层

引言 开放系统互联&#xff08;OSI&#xff0c;Open Systems Interconnection&#xff09;模型&#xff0c;这一国际标准化组织&#xff08;ISO&#xff09;提出的理论框架&#xff0c;是计算机网络通信领域内不可或缺的基础工具。如同语法和句法对于构建和解析语言的重要性一…

Python对PDF文件页面的旋转和切割

Python对PDF文件页面的旋转和切割 利用Python的.rotate()方法和.mediabox属性对PDF页面进行旋转和切割&#xff0c;最终生成一个PDF。下面结合案例进行说明&#xff0c;本示例中的名为split_and_rotate.pdf文件在practice_files文件夹中&#xff0c; 示例&#xff08;1&#…

ShardingSphere分库分表产品介绍

目录 一、ShardingSphere分库分表产品介绍 二、客户端分库分表与服务端分库分表 1、ShardingJDBC客户端分库分表 2、ShardingProxy服务端分库分表 3、ShardingSphere混合部署架构 三、分库分表&#xff0c;能不分就不分&#xff01; 1、为什么要分库分表&#xff1f; 2、…