一、问题理解与建模分析
本题要求处理接龙数列的最长长度问题,核心在于识别数字序列的首位连接规律。根据题目描述,当某数字末位与后续数字首位相同时,可形成有效连接。我们需要建立数学模型:将每个数字抽象为具有首尾两个属性的节点,问题即转化为寻找最长符合条件的节点连接路径。
如何快速获取每个数字的首位数字?这涉及字符串处理技巧。对于输入数字n,可以通过转换为字符串后取首字符和末字符。数字123的首位分别是'1'和'3'。这个预处理步骤的时间复杂度直接影响整体算法效率,建议在O(1)时间内完成。
二、关键代码实现步骤
代码实现分为三个主要模块:输入处理、DP状态转移、结果输出。使用快速IO优化输入输出,避免超时问题。对于每个输入数字,同步记录其首位数字和末位数字。核心代码如下:
string s = to_string(num);
char head = s[0], tail = s.back();
动态规划转移方程的实现需要特别注意状态继承关系。每次处理新数字时,其可能贡献的链长是之前同首位的最大链长+1,同时需要维护当前末位数字对应的最大值。这种双重维护机制确保了时间复杂度控制在O(n)级别。
三、代码注释
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main() {
// 优化输入输出,提高处理速度
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n; // 输入数字的个数
cin >> n;
// dp数组:dp[i]表示以数字i(0-9)结尾的最长接龙序列长度
vector<int> dp(10, 0);
for (int i = 0; i < n; ++i) {
string num; // 当前数字的字符串表示
cin >> num;
// 获取数字的首位和末位数字
int head = num[0] - '0'; // 首位数字
int tail = num.back() - '0'; // 末位数字
// 状态转移:当前数字可以接在相同head的数字后面
// 更新以tail结尾的最长接龙序列长度
dp[tail] = max(dp[tail], dp[head] + 1);
}
// 找出所有可能结尾中的最大值,即最长接龙序列长度
int max_len = *max_element(dp.begin(), dp.end());
// 输出需要删除的数字个数 = 总个数 - 最长接龙序列长度
cout << n - max_len;
return 0;
}点击查看更多内容
为 TA 点赞
评论
共同学习,写下你的评论
评论加载中...
作者其他优质文章
正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
